Подтвердить что ты не робот

Необязательный атрибут выражения в директиве AngularJS

У меня есть настраиваемая директива навигации, которая нуждается в дополнительном атрибуте "отключить", и я не уверен, что это возможно.

В моем основном контроллере:

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

Ответ 1

Вы можете сделать то, что у вас есть, отредактировав свой вызов $eval на

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

потому что вам нужно оценить выражение, содержащееся в attrs.disable, в родительской области, а не в области выделения переменных. Однако, поскольку вы используете '&' синтаксис, он автоматически оценит выражение в родительской области. Поэтому просто сделайте следующее:

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

Fiddle.

Ответ 2

Один из способов сделать то же самое: http://jsfiddle.net/fFsRr/7.

Вы можете заменить todisableornot="rights[1]" своим выражением следующим образом todisableornot="UserService.hasRole('ADMIN,BILLING') && someOtherFn(xxx) || ...".

Теперь, когда Марк Райкок сказал, что свойство todisableornot будет оцениваться в родительской области всякий раз, когда вы вызываете это свойство. Итак,

<li ng-class="{adminRole:todisableornot()}"><a href="{{href}}" id="{{id}}">{{text}}</a></li> будет применять класс adminRole, если свойство todisableornot имеет значение true (в контексте родительской области).

Вы можете проверить это, изменив $scope.rights =[true, false];

Ответ 3

Более подходящей реализацией для этой конкретной проблемы было бы иметь необязательную привязку к простому свойству модели, которое имеет значение, назначенное из вашего сложного оператора. Документация 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>

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

Ответ 4

Недавно я столкнулся с этой проблемой и обнаружил, что у меня есть несколько ссылок (тег script) файла директивы в index.html. После удаления этих дополнительных ссылок проблема исчезла.