简体   繁体   English

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

[英]Optional expression attribute in AngularJS directive

I have a custom navigation directive that needs an optional "disable" attribute, and I'm not sure if it's even possible. 我有一个自定义导航指令需要一个可选的“禁用”属性,我不确定它是否可能。

In my main controller: 在我的主控制器中:

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

});

In my directive: 在我的指令中:

.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>'

    }

});

In my HTML, I want to do something like this: 在我的HTML中,我想做这样的事情:

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

You could make what you have work by chaning your $eval call to 你可以通过chaning $ eval来调用你的工作

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

because you need to evaluate the expression contained in attrs.disable in the parent scope, not the directive's isolate scope. 因为您需要评估父范围中attrs.disable中包含的表达式,而不是指令的隔离范围。 However, since you are using the '&' syntax, it will evaluate the expression in the parent scope automatically. 但是,由于您使用的是'&'语法,它将自动评估父作用域中的表达式。 So just do the following instead: 所以,请执行以下操作:

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

Fiddle . 小提琴

One way of doing the same thing is like this http://jsfiddle.net/fFsRr/7 . 做同样事情的一种方法就是这个http://jsfiddle.net/fFsRr/7

You may replace the todisableornot="rights[1]" with your expression like this todisableornot="UserService.hasRole('ADMIN,BILLING') && someOtherFn(xxx) || ..." . 您可以将todisableornot="rights[1]"替换为您的表达式,如todisableornot="UserService.hasRole('ADMIN,BILLING') && someOtherFn(xxx) || ..."

Now as Mark Rajcok said the property todisableornot will be evaluated in the parent scope whenever you call that property. 现在正如Mark Rajcok所说,只要您调用该属性,就会在父范围内评估属性todisableornot So 所以

<li ng-class="{adminRole:todisableornot()}"><a href="{{href}}" id="{{id}}">{{text}}</a></li> will apply class adminRole if the todisableornot property evaluates to true (in the context of parent scope). <li ng-class="{adminRole:todisableornot()}"><a href="{{href}}" id="{{id}}">{{text}}</a></li>如果todisableornot属性的计算结果为true(在父作用域的上下文中),则将应用类adminRole

You can test this by changing the $scope.rights =[true, false]; 您可以通过更改$scope.rights =[true, false];来测试这个$scope.rights =[true, false];

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. Angular文档反复提到最佳实践是绑定到模型属性而不是函数。 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: 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/ 小提琴: http//jsfiddle.net/YHqLk/

Recently I faced this issue and found that I had multiple references (script tag) of the directive file in index.html. 最近我遇到了这个问题,发现我在index.html中有多个指令文件的引用(脚本标记)。 Once I removed these additional references the issue vanished. 一旦我删除了这些额外的引用,问题就消失了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM