1

AngularJSディレクティブを使用して、アプリケーション全体でフォームの特定の部分を無効にする場合は、ユーザーが特定の役割を持っているかどうか(属性値として与えられます。要素あたり)。ディレクティブのコードは次のようになります。単一の要素に新規/分離スコープを持つ2つの属性ディレクティブ

/** @ngInject */ 
function PermissionDirective() { 
    var directive = { 
     restrict: 'A', 
     scope: true, 
     bindToController: true, 
     controller: controller, 
     controllerAs: 'permission', 
     link: link 
    }; 

    function link(scope, element, attrs) { 
     scope.soPermission = attrs.soPermission; 
    } 

    return directive; 
} 

/** @ngInject */ 
function controller($scope, $attrs, ...) { 
    var permission = this; 
    permission.granted = false; 
    $scope.soPermission = $attrs.soPermission; 
    init(); 

    function init() { 
     var requiredPermission = $scope.soPermission; 

     permission.granted = // determine if user can use element 
    } 
} 

作業には独自のスコープが必要です。 HTMLでの使用には、次のとおりです。

<button type="button" ng-disabled="... || !permission.granted" so-permission="WRITE"> 

すべての罰金は限りso-permissionが新しいスコープを持つ要素で唯一のディレクティブであるとして。しかし、いくつかの要素はまた、新しい/隔離されたスコープを必要とすると思われるconfirmモーダルを使用します。これにより、角度エラーMultiple directives...が発生します。

私の質問は:どのようにこれを回避するのですか? so-permissionディレクティブを修正して内部スコープを取り除き、それでも機能し続けるにはどうすればいいですか?(ライブラリとしてconfirmのものに触れることはできません)

答えて

1

フォーム要素に与える権限は何ですか?たぶん、一歩踏み込んで見て、より単純なHTMLの観点から見ることは可能でしょうか?

ディレクティブを作成する代わりに、ng-attr-readonlyを使用してreadonly属性を関数に割り当てるだけで、存在するかどうかを判断できます。その関数はフォームのコントローラに存在する可能性があります。

<input type="text" ng-attr-readonly="getPermissions()" /> 

と機能:

this.getPermissions = function() { 
    if (this.granted === 'READ') return undefined; 
    return 'readonly'; 
} 

でしょうあなたのような状況のため、このアプローチは動作しますか?

更新:この機能を工場にして再利用します。

angular.module("myApp").factory("PermissionsFactory",PermissionsFactory); 
function PermissionsFactory() { 

    factory = { 
    getPermissions: getPermissions 
    } 
    return factory; 

    function getPermissions(ctrl) { 
    if (ctrl.granted === 'READ') return undefined; 
    return 'readonly'; 
    } 

} 

次に、あなたのコントローラに(あなたはそれを注入していると仮定):

this.getPermissions = PermissionsFactory.getPermissions 

最後に、あなたのHTMLに、関数にコントローラを渡すようにしてください、関数はもはや一部ではないので、コントローラの有効範囲を確認するにはコントローラの有効範囲が必要です。

<input type="text" ng-attr-readonly="getPermissions(permission)" /> 
+0

はい、コントローラー機能のために指令を放棄すると、私にとってはうまくいくかもしれません。私は疑いがある。この機能は、アプリケーション全体で使用する必要があります。これは、ui-routerの状態のいくつかの層で構成されています。私は各コントローラでこの機能を繰り返さないようにしたいと思います。そのための解決策はありますか? – pstobiecki

+0

それを工場にして、それが必要な場所に工場を注入します。次に、関数自体を1か所で変更することができ、アプリケーション全体のすべての用途に伝播します。私は答えを更新しました。おかげさまで – frankrue

+0

しかし、私は別の壁に当たったときです。ユーザーが持つアクセス権は、Webサービスから取得されます。呼び出しに起因する約束は、ui-routerの 'resolve'で解決されます。しかし、コントローラから関数を切り離すと、 'resolve'をもう使用することはできません。 Afaik、Angularでは、約束を強制的に解決するための合理的な方法はありません。関数の値がすぐに必要なので、ここでは役に立たない 'promise.then(){...}'イディオムしかありません。 – pstobiecki

0

角度jsでは、1つの要素上に最大で1つの独立した指令を持つことができます。あなたの指示を飾ることをお勧めします。 /

** @ngInject */ 
     function PermissionDirective() { 
     var directive = { 
     restrict: 'A', 
     link: link 
    }; 

function link(scope, element, attrs) { 
    var getter = $parse(attrs.soPermission); 
    var setter = getter.setter; 
    setter(scope, val); // set value to scope 
    var value = getter(scope); //get value from scope 
} 

return directive; 
} 

はまた、あなたが使用できる範囲$の時計を、ダイナミックに値を同期する:詳細Decorating Directives

0

スコープと通信するために、$の解析サービスを使用する必要があります のため、この記事をチェックしてください。

+0

ありがとうございます。 1)複数のディレクティブ...エラーを取り除く、2)引き続き異なる役割を持つ複数の要素に対してディレクティブを使用することができる、私の問題を解決する方法を説明してください。 – pstobiecki

+0

私の例では、独自のスコープなしでスコープを読み取り編集できます。スコープエラー –

+0

がTrueになることはありません。しかし、私が正しく理解していれば、私がこのようにしたとき、この指令が1つ出現すると、次の発生によって上書きされる状態が生成されます。 – pstobiecki

関連する問題