質問
特定の文字(T、U、V、W、Y、Z)で始まる指令に関する非常に具体的な問題。ディレクティブはselect
要素で使用され、ngOptions
の変更を監視しています。
ngOptions
にAjax要求からデータが入力され、ディレクティブ名は特定の文字で始まります。 w、選択オプションが作成される前に、2番目のウォッチコールバックが発生します。ディレクティブ名が別の文字(a、k、m、n)で始まる場合、オプションが作成された後に2番目のウォッチコールバックが発生します。
さまざまな文字で始まる複数のディレクティブを持つサンプルです。問題を確認するためにコンソールを開きます。
<select w-foo ng-model="bar" ng-options="o.name for o in options"></select>
.
app.controller("test", function ($scope, $timeout) {
// Emulate ajaxed options
$timeout(function () {
$scope.options = [{
name: "aaa",
id: 1
}, {
name: "bbb",
id: 2
}, {
name: "ccc",
id: 3
}];
}, 500);
});
app.directive("wFoo", function () {
return {
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
scope.$watch(attrs.ngOptions.replace(/.*in /, ""), function () {
console.log("w-foo ngOptions changed", element.html());
});
}
};
});
.
上記のコードでは、element.html()
には最初のウォッチコールバック(初期ダイジェスト)に単一の空のoption
が含まれ、2番目のダイジェストには単一の空のoption
も含まれます(AJAXが完成したとき)。
この動作はどこから来ていますか?
解決
この動作を説明するために関与する3つのメカニズムがあります:
-
ウォッチャーは、登録されている同じ順序で実行されます(
$watch
メソッド()のコードを参照してください。 -
ポストリンク機能は、優先順位の逆の順序で実行されます(
priority
プロパティのマニュアルを参照してください。 -
同じ優先順位のディレクティブは、未定義の順序で実行されます。デフォルトの優先順位は
0
ですので、ここにあるすべてのカスタムディレクティブに優先順位があります。select
ディレクティブの優先順位として、実行順序は未定義です。 。気付いたように、「未定義」は少し過剰であり、実際には実行順はアルファベット順(
0
Code ):辞書の先頭に名前を持つディレクティブの優先順位が高くなります。しかし、私の謙虚な意見では、これは文書で明示的に言われていないので、この動作に頼ることはできません。 - カスタム指令のウォッチャーを実行したい場合は、
- あなたがあなたのカスタム指令のウォッチャーを実行したい場合は、
0
One、Well ...否定的な優先順位は禁止されているので、それを確実に行うことはできません。
要約するには、ここに使用されています。各ディレクティブはウォッチャーを登録します。
Name | Priority | Watcher order
--------+------------+--------------
A | 100 | 3rd
B | 0 | 2nd
C | none (= 0) | 1st
.
この問題を解決するには簡単です:
$compile
の後に select
を指定してください。