コントローラ関数のディレクティブの属性にアクセスしようとしています。ただし、アクセスするまでには定義されていません。単純なタイマーを実行すると動作することに気付きました。ディレクティブとスコープの準備ができて使用するように設定された後にのみコードを実行する方法はありますか?
私はそれをいじりました。コンソールが開いていることを確認してください。 http://jsfiddle.net/paulocoelho/uKA2L/1/
以下が、私がフィドルで使用しているコードです。
<div ng-app="testApp" >
<testcomponent text="hello!"></testcomponent>
</div>
var module = angular.module('testApp', [])
.directive('testcomponent', function () {
return {
restrict: 'E',
template: '<div><p>{{text}} This will run fine! </p></div>',
scope: {
text: '@text'
},
controller: function ($scope, $element) {
console.log($scope.text); // this will return undefined
setTimeout(function () {
console.log($scope.text); // this will return the actual value...
}, 1000);
},
link: function ($scope, $element, $attrs) {
console.log($scope.text);
setTimeout(function () {
console.log($scope.text);
}, 1000);
}
};
});
動作するのは、設定すると
scope.text = $attrs.text;
リンクおよびコントローラー機能内。 2wayデータバインディングがないため、これは最初にのみ機能します。ただし、 $ attrs.observe を使用できます。
フィドルを参照してください: http://jsfiddle.net/JohannesJo/nm3FL/2/
分離スコープでは、「@」で定義されたローカルスコーププロパティにリンク関数でアクセスできません。 @remigioで既に述べたように、そのようなローカルスコーププロパティはその時点ではundefined
です。 (補間された)値を非同期的に取得するには、$ attrs。$ observe()または$ scope。$ watch()を使用する必要があります。
属性に定数値を渡す場合(つまり、補間が不要、つまり属性の値に{{}}が含まれない場合)、「@」、$ observer、または$ watchの必要はありません。 $ attrsを使用できます。属性名 @hugoが示唆するように1回、または数値またはブール値を渡して適切な型を取得したい場合は、$ scope。$ eval($ attrs。属性名)一度。
「=」を使用してローカルスコーププロパティを親スコーププロパティにデータバインドすると、プロパティの値がリンク関数で利用可能になります($ observe、$ watch、または$ evalは不要)。
Angular 1.3なので、bindToController
を使用できます。使用方法のサンプルを次に示します。ここでは、属性をスコープに追加してからbindToController
を使用しますコントローラ内でそれを使用するには:
var module = angular.module('testApp', [])
.directive('testcomponent', function () {
return {
restrict: 'E',
template: '<div><p>{{text}} This will run fine! </p></div>',
scope: {
text: '@text'
},
controller: function () {
console.log(this.text);
},
controllerAs: 'vm',
bindToController: true
};
});
Angular 1.3では、bindToControllerと呼ばれるディレクティブ定義オブジェクトに新しいプロパティが導入されており、これはまさにそれを実行します。 controllerAsを使用する分離スコープを持つディレクティブでtrueに設定すると、コンポーネントのプロパティはスコープではなくコントローラーにバインドされます。つまり、Angularは、コントローラがインスタンス化されたときに、分離されたスコープバインディングの初期値がこれで利用可能であり、将来の変更も自動的に利用できることを確認します。
代わりに$scope
ディレクティブの属性値を取得するには、個人的には$attrs
controller
関数、またはattrs
関数の3番目のパラメーターでのlink
のみ。タイムアウトなしで次のコードでcontroller
から属性値を取得しても問題ありません。
var module = angular.module('testApp', [])
.directive('testcomponent', function () {
return {
restrict: 'E',
template: '<div><p>{{text}} This will run fine! </p></div>',
scope: {
text: '@text'
},
controller: ['$scope','$attrs', function ($scope, $attrs) {
console.log($attrs.text); // just call to the $attrs instead $scope and i got the actual value
$scope.text = $attrs.text; //assign attribute to the scope
}]
};
});
ディレクティブを使用してビューに挿入するためにディレクティブからこの値にアクセスしている場合、$ compile apiを使用してこの属性にアクセスし、次のようなことを行うことができます。
var string = "<div> " + scope.text + "</div>";
$compile(string)(scope, function(cloned, scope){
element.append(cloned);
});