13

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

在我的主控制器中:

.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

4 回答 4

8

您可以通过将 $eval 调用更改为

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

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

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

小提琴

于 2013-03-05T17:39:56.507 回答
0

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

于 2014-06-27T06:29:45.280 回答
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>adminRole如果todisableornot属性评估为真(在父范围的上下文中),将应用类。

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

于 2013-03-06T04:31:32.003 回答
0

A more appropriate implementation for this specific problem would be to have an optional binding to a simple model property that has its value assigned from your complex statement. The Angular documentation repeatedly mentions that the best practice is to bind to model properties and not to functions. The "&" binding for directives is primarily useful for implementing callbacks, where you need to passing data from the directive to its parent.

Implementing an optional binding looks like this:

Code:

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>

Fiddle: http://jsfiddle.net/YHqLk/

于 2014-06-23T14:27:11.060 回答