【问题标题】:Angular.js and ng-switch-when - emulating enumAngular.js 和 ng-switch-when - 模拟枚举
【发布时间】:2013-05-13 17:34:54
【问题描述】:

我想在我的控制器逻辑中引入一些枚举以实现某种类型安全,所以例如我创建了这样的东西:

var app = angular.module('myApp', []);
var StateEnum = Object.freeze({"login":1, "logout":2})
function LoginCheckCtrl($scope) {
    $scope.stateEnum = StateEnum
    $scope.loginData = StateEnum.login
    $scope.login = function() {
        console.log($scope.loginData  ? 'logged in' : 'not logged in');
        $scope.loginData = StateEnum.logout;
    };
    $scope.logout = function() {
        console.log($scope.loginData ? 'logged in' : 'not logged in');
        $scope.loginData = StateEnum.login;
    };
}

在我的示例页面中,我会有这样的内容:

<div ng-controller="LoginCheckCtrl">
   <div ng-switch on="loginData"> 
      <div ng-switch-when="stateEnum.login" ng-include="'login'"></div>
      <div ng-switch-when="stateEnum.logout" ng-include="'logout'"></div>
   </div>
</div>

<script type="text/ng-template" id="login">
    <button ng-click="login()">Login</button>
</script>

<script type="text/ng-template" id="logout">
    <button ng-click="logout()">Logout</button>
</script>

但是ng-switch-when 不想工作。只有当我用整数手动替换 ng-swith-when 中的值时它才有效,例如 1,2。

这里有一些小提琴来证明这一点:

http://jsfiddle.net/jNxyE/3/

http://jsfiddle.net/4Jg7M/2/

现在,如您所见,第一个显然不起作用,而第二个起作用 - 这意味着单击按钮时它会更改按钮。

我认为这个问题是var StateEnum = Object.freeze({"login":1, "logout":2})

是否可以在我的 html 中使用我的枚举,以便 ng-switch-when 可以正常工作(如第二小提琴)?

【问题讨论】:

    标签: javascript angularjs enums


    【解决方案1】:

    我想我会创建一个可以包含所有枚举的服务:

    angular.module('Enums', []).
       factory('Enum', [ function () {
    
          var service = {
            freeze: {login:1, logout:2 },
              somethingelse: {abc:1,def:2}
          };
    
         return service;
    
        }]);
    

    您的应用定义如下:

    var app = angular.module('myApp', ['Enums']);
    

    然后您的控制器可以在需要时注入它们:

    function LoginCheckCtrl($scope, Enum) {
        if (1==Enum.freeze.login) // as an example
        if (1==Enum.somethingelse.abc)  // another example
    

    服务是单例的,因此这将有效地为您提供一组您可以定义的枚举。

    至于 ngSwitch when 指令,我认为它需要一个字符串(如果我错了,请纠正我)。几个参考:

    https://groups.google.com/forum/?fromgroups#!topic/angular/EH4W0y93ZAA https://github.com/angular/angular.js/blob/master/src/ng/directive/ngSwitch.js#L171

    实现您想要的另一种方法是使用ng-show/ng-hide

    <div ng-include="'login'" ng-show='stateEnum.login==loginData' ...>
    

    【讨论】:

    • 好的,但问题不在于我如何管理我的枚举,即使服务是个好主意,问题是“视图” - html 似乎不适用于我的枚举 - 首先小提琴没有大小写匹配。
    • 您是否定义了外部视图?我的意思是 login.html 在哪里,在小提琴上做有点难,我建议你使用 plunkr。
    • 我没有任何外部视图 afaik,所有的 html 都在 html 框中
    • @Andna 我相信它需要一个字符串,因此您可能需要考虑在执行 ng-include 而不是使用开关的 div 上放置一些 ng-show/ng-hide。
    • 没错。 ng-switch-when 需要一个字符串。所以你必须找到另一种解决方案来使用一些解决方法。
    【解决方案2】:

    你在stackoverflow上看过这个答案吗?: Ways to enum

    最佳答案来自 2008 年,因此请查看较新/最新的帖子以获取线索。当我阅读它们时,您可以获得所需的任何原语的答案,但我尚未对此进行测试。任何人都可以从这篇文章中提出与 Angular 一起使用的最佳答案吗?

    【讨论】:

    • 这是不久前的事,但我终于做了你链接的帖子中建议的事情。
    • Adna 我是 javascript 新手,该帖子中的许多建议令人不知所措。如果你修改了你的小提琴,新手看看它会很棒..提示像我这样的提示:-)
    【解决方案3】:

    我建议使用angular.Module.constant。例如:

    var app = angular.module('app', []);
    app.constant('Weekdays', {
        Monday: 1,
        Tuesday: 2,
        Wednesday: 3,
        Thursday: 4,
        Friday: 5,
        Saturday: 6,
        Sunday: 7
    });
    app.controller('TestController', function(Weekdays) {
        this.weekday = Weekdays.Monday;
    });
    

    【讨论】:

      【解决方案4】:

      我在一个名为 Enums 的单独文件中声明了一些枚举。 (我用 TypeScript 做的)在 Angular 应用程序的控制器中,我有这样的东西:

      var app = angular.module("Sample", ["ngAnimate"])
      app.controller("Messages", function ($scope, $sce, $interval, $log, $http) {
          $scope.enums = Enums;
      };
      

      另一个文件中的枚举位于一个名为 Enums 的 var 中。

      现在你可以使用它,甚至更有创意:

      ng-show="anotherVAr == enums.enumOne.VALUE"
      

      【讨论】:

        【解决方案5】:

        这是一个真实的例子,展示了如何使用 Angular 和标准 JavaScript 和 BootStrap 来模拟枚举。这是为了显示订单的详细信息,也称为工单。

        将您的枚举定义为 Angular 常量:

         app = angular.module("MyApp", [])
        .constant('ENUMS',
            {
                TicketStatusText: { 0: 'Open', 3: 'Ready', 1: 'Closed', 2: 'Overring' },
                TicketStatus: {Open:0, Ready:3, Closed:1, Overring:2}
            }
            )
        

        您的控制器代码应如下所示:

        app.controller("TicketsController", function ($scope, $http, ENUMS) {
        $scope.enums = ENUMS;
        

        您的带有 BootStrap 的 HTML 应该如下所示:

        <table>
        <tr ng-repeat="ticket in tickets" ng-class="{danger:ticket.CurrentStatus==enums.TicketStatus.Overring}">
        <td>
        <strong>{{ticket.TransNumber}}</strong>
        </td>
        <td>
        {{enums.TicketStatusText[ticket.CurrentStatus]}}
        </td>
        

        注意在ng-class中结合BootStrap我们将ticket模型的当前状态与enums.TicketStatusText.Overring进行比较;这将更改任何具有 Overring 状态 (2) 的工单的行颜色。

        同样在其中一列中,我们希望将工单状态显示为字符串而不是整数。所以使用这个:{{enums.TicketStatusText[ticket.CurrentStatus]}}

        【讨论】:

          【解决方案6】:

          服务

          var app = angular.module('myApp', []);
          
          app.factory('Enum', function () {
                    return {
                      Action: {login:1, logout:2 },
                      Status: {open:1, close:2}
                    };
                  });
          

          控制器

          app.controller('TestController', function($scope, Enum) {
              $scope.x = Enum.Action.logout;
              $scope.y= Enum.Status.close;
          });
          

          【讨论】:

            【解决方案7】:

            ng-switch-when 不支持表达式,需要字符串或数字。 打字稿转译器可以在字符串和数字之间创建反向映射,以便 stateEnum[1]='login' 在您的情况下(或者您可以使用实用程序函数自己创建它)。 所以你可以简单地这样做,虽然有点丑但是很干净。

            <div ng-controller="LoginCheckCtrl">
               <div ng-switch on="stateEnum[loginData]"> 
                  <div ng-switch-when="login" ng-include="'login'"></div>
                  <div ng-switch-when="logout" ng-include="'logout'"></div>
               </div>
            </div>
            

            【讨论】:

              猜你喜欢
              • 2015-10-02
              • 1970-01-01
              • 2014-06-23
              • 2017-12-13
              • 2013-06-30
              • 1970-01-01
              • 1970-01-01
              • 2017-05-09
              • 1970-01-01
              相关资源
              最近更新 更多