在有角度的 HTML 页面中使用 Typescript 枚举的正确方法(例如,有角度的 ng-class)
Posted
技术标签:
【中文标题】在有角度的 HTML 页面中使用 Typescript 枚举的正确方法(例如,有角度的 ng-class)【英文标题】:Correct way to utilize Typescript enum in angular HTML pages (e.g. angular ng-class) 【发布时间】:2015-10-20 14:19:08 【问题描述】:Angular 和打字稿的新手。
我有如下打字稿枚举
public enum MyEnum
A = 0,
B = 1,
C = 2
作用域变量 as-
$scope.myLetter: MyEnum = MyEnum.B;
进行枚举检查的正确方法是什么?
方案一:比较html页面中枚举的整数值-
<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:'RyanNerd' 在Angular.js and ng-switch-when - emulating enum
给出的答案对我来说,选项 2 更可取,其余选项将 ng-class 值检查为字符串,这不会给我们提供静态类型强制。如果有的话,请分享您的观点或任何其他更好的选择。
【问题讨论】:
【参考方案1】:从控制器作用域方法中获取类名
我不喜欢让控制器知道类名的想法。
您可以将转换器功能添加到范围:
$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]);
])
【讨论】:
【参考方案2】:您还可以在控制器中构建类对象并在视图中将其设置为表达式(使用括号表示法)。
例子:-
$scope.panelClass = ;
$scope.panelClass[MyEnum.A] = 'classA';
$scope.panelClass[MyEnum.B] = 'classB';
$scope.panelClass[MyEnum.C] = 'classC';
如果您的 typescript 版本支持(具有 polyfill 支持),您可以将以上内容编写为简写语法 (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>
【讨论】:
【参考方案3】:当我们需要明确引用数字值时,我们通常需要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>
【讨论】:
【参考方案4】:我也遇到过这个问题。
这是我的解决方案:
我在控制器中创建了一个函数,它为我的枚举的每个值返回一个布尔值。
在我的controller.ts中
export class AController
public TestEnumA(): boolean
return this.scope.field == MyEnum.A;
public TestEnumB(): boolean
return this.scope.field == MyEnum.B;
在我看来.html
<div ngController="AController as controllerAlias">
<div class="a-class" ng-class="'classA-true': controllerAlias.TestEnumA(), 'classB-true': controllerAlias.TestEnumB()"><div>
</div>
为什么我选择了这个解决方案?
这样,我不硬编码控制器中的 css 类(在控制器中硬编码 css 类,确保视图的可维护性不是一个好主意)
这样,我不硬编码您的 ng-class 中的枚举值;
这样,我仍然受益于自动代码完成和编译验证。
【讨论】:
【参考方案5】:您可以在 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>
【讨论】:
以上是关于在有角度的 HTML 页面中使用 Typescript 枚举的正确方法(例如,有角度的 ng-class)的主要内容,如果未能解决你的问题,请参考以下文章