在有角度的 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。在上述用例中,我没有看到使用enums 的明确用例。数组可以正常工作,如下所示:

((): 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)的主要内容,如果未能解决你的问题,请参考以下文章

我可以在有角度的项目中重新安装npm来修复它吗?

如何在单页应用程序中以角度将数据从一页传递到另一页

typescri枚举enum

HTML 页面到 PDF(角度 js 和 d3 图表)

如何在 Ionic 中将文本转换为 html 对象

如何在有条件的情况下改变状态 - React