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

时间:2013-03-05 14:37:52

标签: javascript angularjs angularjs-directive

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

在我的主控制器中:

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

4 个答案:

答案 0 :(得分:8)

您可以通过将$ eval调用转至

来完成您的工作
scope.$parent.$eval(attrs.disable);

因为您需要评估父作用域中attrs.disable中包含的表达式,而不是指令的隔离范围。但是,因为你正在使用'&amp;'语法,它将自动评估父作用域中的表达式。所以,请执行以下操作:

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

Fiddle

答案 1 :(得分:0)

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

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

现在正如Mark Rajcok所说,只要您调用该属性,就会在父作用域中评估属性todisableornot。所以

如果<li ng-class="{adminRole:todisableornot()}"><a href="{{href}}" id="{{id}}">{{text}}</a></li>属性的计算结果为true(在父作用域的上下文中),

adminRole将应用类todisableornot

您可以通过更改$scope.rights =[true, false];

进行测试

答案 2 :(得分:0)

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

实现可选绑定如下所示:

代码:

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/

答案 3 :(得分:0)

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