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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15226531/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 23:58:10  来源:igfitidea点击:

Optional expression attribute in AngularJS directive

javascriptangularjsangularjs-directive

提问by boyceofreason

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

回答by Mark Rajcok

You could make what you have work by chaning your $eval call to

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

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

because you need to evaluate the expression contained in attrs.disablein the parent scope, not the directive's isolate scope. However, since you are using the '&' syntax, it will evaluate the expression in the parent scope automatically. So just do the following instead:

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

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

Fiddle.

小提琴

回答by Rajkamal Subramanian

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 todisableornotwill be evaluated in the parent scope whenever you call that property. So

现在正如 Mark Rajcok 所说,todisableornot每当您调用该属性时,都会在父作用域中评估该属性。所以

<li ng-class="{adminRole:todisableornot()}"><a href="{{href}}" id="{{id}}">{{text}}</a></li>will apply class adminRoleif the todisableornotproperty evaluates to true (in the context of parent scope).

<li ng-class="{adminRole:todisableornot()}"><a href="{{href}}" id="{{id}}">{{text}}</a></li>adminRole如果todisableornot属性评估为真(在父作用域的上下文中),则将应用类。

You can test this by changing the $scope.rights =[true, false];

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

回答by Hyman A.

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.

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

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/

回答by user1158300

Recently I faced this issue and found that I had multiple references (script tag) of the directive file in index.html. Once I removed these additional references the issue vanished.

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