【问题标题】:Optional expression attribute in AngularJS directiveAngularJS 指令中的可选表达式属性
【发布时间】:2013-03-05 14:37:52
【问题描述】:

我有一个自定义导航指令,它需要一个可选的“禁用”属性,我不确定它是否可能。

在我的主控制器中:

.controller('NavCtrl', ['UserResource','RoleResource'], function(UserResource,RoleResource){
      var user = UserResource.getUser();
      var roles = RoleResource.getRoles();
      UserService.init(user, roles); //????

});

在我的指令中:

.directive('navItem', function(){
    return{
        restrict: 'A',
        scope: {
            text: '@',
            href: '@',
            id: '@',
            disable: '&'

        },
        controller: function($scope, $element, $attrs){
            $scope.disabled = ''; //Not sure I even need a controller here
        },
        replace: true,
        link: function(scope, element, attrs){
            scope.$eval(attrs.disable);
        },
        template: '<li class="{{disabled}}"><a href="{{href}}" id="{{id}}">{{text}}</a></li>'

    }

});

在我的 HTML 中,我想做这样的事情:

<div data-nav-item text="My Text" href="/mytemplate.html" id="idx"
     disable="UserService.hasRole('ADMIN,BILLING') && someOtherFn(xxx) || ...">

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案1】:

    你可以把你的 $eval 调用改为

    scope.$parent.$eval(attrs.disable);
    

    因为您需要在父范围内评估 attrs.disable 中包含的表达式,而不是指令的隔离范围。但是,由于您使用的是 '&' 语法,它会自动评估父范围内的表达式。因此,只需执行以下操作:

    if(angular.isDefined(attrs.disable)) {
        scope.disable();
    }
    

    Fiddle.

    【讨论】:

    • 对不起,我不小心按了 ctrl+s.. 小提琴已根据我的更改进行了更新。您能否更新小提琴链接。再次抱歉。
    • @rajkamal,即使您保存了新版本,上面指向小提琴的链接仍应将人们带到原始版本。您还必须点击“基本”按钮才能让人们看到您的版本,所以不会造成任何伤害。
    • 这正是我所需要的。谢谢!
    • 哇,看到 scope.disable();电话真的帮助了我。直到我看到它,我才掌握了 '&' 的全部力量。
    【解决方案2】:

    做同样事情的一种方法是http://jsfiddle.net/fFsRr/7

    您可以将todisableornot="rights[1]" 替换为todisableornot="UserService.hasRole('ADMIN,BILLING') &amp;&amp; someOtherFn(xxx) || ..." 这样的表达式。

    现在,正如 Mark Rajcok 所说,只要您调用该属性,todisableornot 属性就会在父范围内进行评估。所以

    如果todisableornot 属性的计算结果为真(在父作用域的上下文中),&lt;li ng-class="{adminRole:todisableornot()}"&gt;&lt;a href="{{href}}" id="{{id}}"&gt;{{text}}&lt;/a&gt;&lt;/li&gt; 将应用类adminRole

    您可以通过更改 $scope.rights =[true, false]; 来测试这一点

    【讨论】:

      【解决方案3】:

      对于这个特定问题,一个更合适的实现是对一个简单模型属性的可选绑定,该属性的值是从您的复杂语句中分配的。 Angular 文档反复提到最佳实践是绑定到模型属性而不是函数。指令的“&”绑定主要用于实现回调,您需要将数据从指令传递到其父级。

      实现可选绑定如下所示:

      代码:

      angular.module("testApp", [])
      .controller("testCtrl", ["$scope", function testCtrl($scope) {
          $scope.myFlag = false;
      }])
      .directive("testDir", function testDir() {
          return {
              restrict: "EA",
              scope: {
                  identity: "@",
                  optional: "=?"
              },
              link: function testDirLink($scope, $element, $attrs) {
                  if (typeof $scope.optional == "undefined") {
                      $scope.description = "optional was undefined";
                  }
                  else {
                      $scope.description = "optional = '" + $scope.optional + "'";
                  }
              },
              template: "<div>{{identity}} - {{description}}</div>"
          };
      });
      

      HTML:

      <div ng-app="testApp" ng-controller="testCtrl">
          <test-dir identity="one" optional="myFlag"></test-dir>
          <test-dir identity="two"></test-dir>
      </div>
      

      小提琴:http://jsfiddle.net/YHqLk/

      【讨论】:

        【解决方案4】:

        最近我遇到了这个问题,发现我在 index.html 中有多个指令文件的引用(脚本标记)。一旦我删除了这些额外的引用,问题就消失了。

        【讨论】:

          猜你喜欢
          • 2015-06-01
          • 2015-10-15
          • 1970-01-01
          • 1970-01-01
          • 2013-11-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-22
          相关资源
          最近更新 更多