angularおよびTypeScriptの新機能。
次のようにTypeScript列挙型があります
public enum MyEnum{
A = 0,
B = 1,
C = 2
}
スコープ変数as-
$scope.myLetter: MyEnum = MyEnum.B;
列挙チェックを行う正しい方法は何ですか?
オプション1:htmlページのenumの整数値を比較します-
<div ng-class="{classA: myLetter === 0, classB: myLetter === 1, classC: myLetter === 2}">Test panel</div>
オプション2:コントローラースコープメソッドからクラス名を取得する
$scope.getClass(value: myLetter): string{
if(value === MyEnum.A)
return 'classA';
if(value === MyEnum.B)
return 'classB';
if(value === MyEnum.C)
return 'classC';
}
そして、HTML要素として
<div ng-class='getClass(myLetter)'>Test panel</div>
オプション3:Angular.jsおよびng-での 'RyanNerd'による回答switch-when-列挙型のエミュレート
私にとってはオプション2が望ましいです。残りのオプションでは、ng-class値を文字列としてチェックします。これにより、静的な型の強制は行われません。もしあれば、あなたの意見や他のより良いオプションを共有してください。
コントローラースコープメソッドからクラス名を取得する
コントローラにクラス名を知ってもらうという考えは好きではありません。
スコープにコンバーター関数を追加できます。
$scope.myEnumName = (value: MyEnum) => MyEnum[value];
テンプレートで使用します:
ng-class="{'A':'ClassA', 'B':'ClassB', 'C':'ClassC'}[myEnumName(myLetter)]"
またはスイッチ機能を追加
$scope.switchMyEnum =
<T>(value: MyEnum, cases: { [value: string]: T }) => cases[MyEnum[value]];
テンプレート:
ng-class="switchMyEnum(myLetter, {'A':'ClassA', 'B':'ClassB', 'C':'ClassC'})
myLetter
スイッチのみが必要な場合:
$scope.switchMyLetter =
<T>(cases: { [value: string]: T }) => cases[MyEnum[$scope.myLetter]];
テンプレート:
ng-class="switchMyLetter({'A':'ClassA', 'B':'ClassB', 'C':'ClassC'})
多くのスコープで多数の列挙を使用する場合:
angular.module("MyApp", [])
.run(["$rootScope", (root: {}) => {
function registerSwitchers(...enumInfos: [string, { [value: number]: string }][]) {
enumInfos.forEach(enumInfo => {
var switcherName = enumInfo[0]
var enumType = enumInfo[1]
root[switcherName] = (value: any, cases: { [value: string]: any }) => cases[enumType[value]];
});
}
registerSwitchers(
["switchMyEnum1", MyEnum1],
["switchMyEnum2", MyEnum2]);
}])
また、コントローラーでクラスオブジェクトを構築し、ビューで式(括弧表記)として設定することもできます。
例:-
$scope.panelClass = {};
$scope.panelClass[MyEnum.A] = 'classA';
$scope.panelClass[MyEnum.B] = 'classB';
$scope.panelClass[MyEnum.C] = 'classC';
TypeScriptバージョンがサポートしている(ポリフィルをサポートしている)場合は、上記を簡易構文(ES6)として記述できるため、次のように書き換えることができます。
$scope.panelClass = {
[MyEnum.A]:'classA',
[MyEnum.B]:'classB',
[MyEnum.C]:'classC'
};
そしてそれを次のように使用します:
<div ng-class="panelClass[myLetter]">Test panel</div>
これは、簡単なng-class式に似ています。
<div ng-class="{0:'classA', 1:'classB', 2:'classC'}[myLetter]">Test panel</div>
RootScopeで列挙型を設定できます
angular
.module('moduleName', [])
.run(['$rootScope', function ($rootScope) {
$rootScope.Enum = PathToEnum.Enum;
}]);
ビューで
<div ngController="AController">
<div class="class" ng-class="{$root.Enum.A: 'classA', $root.Enum.B: 'classB'}[valueInScope]">
</div>
</div>
通常、数値を明示的に参照する必要がある場合は、Enums
が必要です。上記のユースケースでは、enum
sを使用する明示的なユースケースは見当たりません。以下に示すように、配列は正常に機能します。
((): void => {
var ClassConstant: string[] = ['classA', 'classB', 'classC'];
angular
.module('app', [])
.constant('ClassConstant', ClassConstant)
.controller('AppController', ($scope, ClassConstant) => {
$scope.setClass = (classname: string) => {
return ClassConstant[classname];
};
});
})();
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-app="app">
<div ng-controller="AppController">
<div ng-class="{{setClass(myLetter)}}">1</div>
</div>
</body>
</html>
私もこの質問に直面しました。
これは私のソリューションです:
列挙型の各値に対してブール値を返す関数をコントローラーで作成します。
私のcontroller.tsで
export class AController {
public TestEnumA(): boolean {
return this.scope.field == MyEnum.A;
}
public TestEnumB(): boolean {
return this.scope.field == MyEnum.B;
}
}
私のview.htmlで
<div ngController="AController as controllerAlias">
<div class="a-class" ng-class="{'classA-true': controllerAlias.TestEnumA(), 'classB-true': controllerAlias.TestEnumB()}"><div>
</div>
なぜこのソリューションを選択したのですか?
このように、I ハードコードしないでくださいコントローラーのcssクラス(コントローラーのcssクラスをハードコードしました。ビューの保守性を確保することはお勧めできません)
このように、I ハードコードしないでください ng-classの列挙値;
このように、自動コード補完のメリット AND コンパイル時の検証。