web-dev-qa-db-ja.com

AngularJSディレクティブのオプションの式属性

オプションの「disable」属性を必要とするカスタムナビゲーションディレクティブがありますが、それが可能かどうかさえわかりません。

私のメインコントローラーでは:

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

$ evalの呼び出しをに変更することで、自分が持っているものを作成できます。

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

ディレクティブの分離スコープではなく、親スコープのattrs.disableに含まれる式を評価する必要があるためです。ただし、「&」構文を使用しているため、親スコープの式が自動的に評価されます。したがって、代わりに次のことを行ってください。

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

フィドル

8
Mark Rajcok

この特定の問題のより適切な実装は、複雑なステートメントから値が割り当てられている単純なモデルプロパティへのオプションのバインディングを持つことです。 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>

フィドル: http://jsfiddle.net/YHqLk/

0
Jack A.

同じことを行う1つの方法は、次のようなものです 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プロパティが(親スコープのコンテキストで)trueと評価された場合、クラスtodisableornotを適用します。

_$scope.rights =[true, false];_を変更することでこれをテストできます

最近、この問題に直面し、index.htmlにディレクティブファイルの複数の参照(スクリプトタグ)があることがわかりました。これらの追加の参照を削除すると、問題はなくなりました。

0
user1158300