7

AngularJS ディレクティブに関して、別のディレクティブ内からディレクティブを呼び出している状況に遭遇しました。次の質問があります。

  1. リンク関数で scope.bindValue を参照できないのはなぜですか? scope.bindValue から値を計算してスコープに設定する方法はありますか?
  2. scope:{} で「@」を使用してサブディレクティブをバインドできるのに、リンク関数で scope.value = attrs.value を使用できないのはなぜですか?

以下のすべてはhttp://jsfiddle.net/sdg9/AjDtt/13/で見ることができます

HTML:

<directive bind-value="12" value="7"></directive>

JS:

var myApp = angular.module('myApp', []);
var commonTemplate = '<div>{{name}} bind-value is: {{bindValue}} </div><div>{{name}} value is: {{value}} </div><div>{{name}} add one to bind-value is: {{addOneBindValue}} </div><div>{{name}} add one to value is: {{addOneValue}} </div><br/>';

myApp.directive('directive', function () {
    return {
        scope: {
            bindValue: "@",
        },
        template: commonTemplate + '<br/><sub-directive bind-value="{{value}}" value="{{value}}"></sub-directive>',
        restrict: 'E',
        link: function (scope, element, attrs) {
            scope.name = "Directive";
            scope.value = attrs.value;
            scope.addOneBindValue = parseInt(scope.bindValue) + 1;
            scope.addOneValue = parseInt(scope.value) + 1;
        }
    };
});


myApp.directive('subDirective', function () {
    return {
        scope: {
            bindValue: "@"
        },
        template: commonTemplate,
        restrict: 'E',
        link: function (scope, element, attrs) {   
            scope.name = "SubDirective";
            scope.value = attrs.value;
            scope.addOneBindValue = parseInt(scope.bindValue) + 1;
            scope.addOneValue = parseInt(scope.value) + 1;
        }
    };
});

出力:

Directive bind-value is: 12
Directive value is: 7
Directive add one to bind-value is: null    <--- why?
Directive add one to value is: 8    

SubDirective bind-value is: 7
SubDirective value is:                      <--- why?
SubDirective add one to bind-value is: null
SubDirective add one to value is: null  
4

1 に答える 1

13

補間された属性 (つまり、{{}} を使用する属性) および「@」で定義された分離スコープ プロパティは、リンク関数の実行時に使用できません。attrs.$observe()(またはscope.$watch( @ property here, ...)) を使用して値を (非同期に) 取得する必要があります。

そのため、scope.bindValue使用しようとしているときに使用できません。

同様に、サブディレクティブでは、属性valueに {{}} があるため、使用しようとしてもその値を使用できません。これには、「@」ディレクティブ プロパティも定義する必要があります。

ワーキングフィドル

非同期要件の理由は、{{}} 内の項目が変更される可能性があり、通常はディレクティブに通知してもらいたい (そして、「addOne」値を更新するなどの何かを実行する) ためです。'@' は通常、属性値に {{}} が含まれる場合に分離スコープで使用されます。

属性値が定数であり、テンプレート (または templateUrl) で値を使用しない場合は、おそらく「@」を使用しないでください。リンク関数でattrs.attrNameは、値が文字列のscope.$eval(attrs.attrName)場合、または属性が数値またはブール値のparseInt(attrs.attrName)場合 (または数値であることがわかっている場合) にのみ使用します。

于 2013-03-15T17:54:35.053 に答える