【问题标题】:Correct way to utilize Typescript enum in angular HTML pages (e.g. angular ng-class)在有角度的 HTML 页面中使用 Typescript 枚举的正确方法(例如,有角度的 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 值检查为字符串,这不会给我们提供静态类型强制。如果有的话,请分享您的观点或任何其他更好的选择。

【问题讨论】:

    标签: angularjs typescript


    【解决方案1】:

    从控制器作用域方法中获取类名

    我不喜欢让控制器知道类名的想法。

    1. 您可以将转换器功能添加到范围:

      $scope.myEnumName = (value: MyEnum) => MyEnum[value];
      

      并在模板中使用它:

      ng-class="{'A':'ClassA', 'B':'ClassB', 'C':'ClassC'}[myEnumName(myLetter)]"
      
    2. 或者添加开关功能

      $scope.switchMyEnum =
          <T>(value: MyEnum, cases: { [value: string]: T }) => cases[MyEnum[value]];
      

      模板:

      ng-class="switchMyEnum(myLetter, {'A':'ClassA', 'B':'ClassB', 'C':'ClassC'})
      
    3. 如果你只需要myLetter开关:

      $scope.switchMyLetter =
          <T>(cases: { [value: string]: T }) => cases[MyEnum[$scope.myLetter]];
      

      模板:

      ng-class="switchMyLetter({'A':'ClassA', 'B':'ClassB', 'C':'ClassC'})
      
    4. 如果您想在多个范围内使用多个枚举:

      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>
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-06-22
              • 1970-01-01
              • 1970-01-01
              • 2016-12-05
              • 2019-10-28
              • 2014-10-18
              • 1970-01-01
              相关资源
              最近更新 更多