AngularJS指令中的可选表达式属性

Optional expression attribute in AngularJS directive

本文关键字:表达式 属性 指令 AngularJS      更新时间:2023-09-26

我有一个自定义导航指令,需要一个可选的"disable"属性,我不确定这是否可能。

在我的主控制器中:

.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) || ...">

您可以通过更改对

的$eval调用来使您所拥有的工作。
scope.$parent.$eval(attrs.disable);

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

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

小提琴。

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

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

现在,正如Mark rajcock所说,每当您调用该属性时,属性todisableornot将在父作用域中进行评估。所以

如果todisableornot属性的值为true(在父作用域的上下文中),

<li ng-class="{adminRole:todisableornot()}"><a href="{{href}}" id="{{id}}">{{text}}</a></li>将应用adminRole类。

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

对于这个特定的问题,一个更合适的实现是对一个简单的模型属性有一个可选的绑定,该属性的值是从您的复杂语句中分配的。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/

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