[解決済み】AngularJSでディレクティブからディレクティブを追加する
質問
を処理するディレクティブを作成しようとしています。
ディレクティブを追加する
を宣言している要素に追加します。
例えば、次のようなディレクティブを作りたいのです。
datepicker
,
datepicker-language
と
ng-required="true"
.
もしこれらの属性を追加してから
$compile
明らかに無限ループが発生するので、必要な属性がすでに追加されているかどうかをチェックしているのです。
angular.module('app')
.directive('superDirective', function ($compile, $injector) {
return {
restrict: 'A',
replace: true,
link: function compile(scope, element, attrs) {
if (element.attr('datepicker')) { // check
return;
}
element.attr('datepicker', 'someValue');
element.attr('datepicker-language', 'en');
// some more
$compile(element)(scope);
}
};
});
もちろん、もし私が
$compile
要素に設定すると、属性は設定されますが、ディレクティブはブートストラップされません。
この方法は正しいのでしょうか、それとも私のやり方が間違っているのでしょうか?同じ動作を実現するための良い方法はありますか?
UDPATE
という事実を考えると
$compile
はこれを実現する唯一の方法ですが、最初のコンパイルパスをスキップする方法はありますか(要素に複数の子が含まれる場合があります)?おそらく
terminal:true
?
アップデイト2
: ディレクティブを
select
要素で、予想通りコンパイルが2回実行され、つまり、予想される
option
s.
解決方法は?
一つの DOM 要素に複数のディレクティブがあり、かつ、そのうちの一つが
の順番で適用することが重要です。
priority
プロパティで
を適用します。数字の大きい方が先に実行されます。指定しない場合、デフォルトの優先順位は0です。
EDIT
: 議論の結果、これが完全な動作ソリューションです。キーポイントは
属性を削除する
:
element.removeAttr("common-things");
であり、さらに
element.removeAttr("data-common-things");
(を指定した場合)。
data-common-things
を指定します。)
angular.module('app')
.directive('commonThings', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true, //this setting is important, see explanation below
priority: 1000, //this setting is important, see explanation below
compile: function compile(element, attrs) {
element.attr('tooltip', '{{dt()}}');
element.attr('tooltip-placement', 'bottom');
element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html
return {
pre: function preLink(scope, iElement, iAttrs, controller) { },
post: function postLink(scope, iElement, iAttrs, controller) {
$compile(iElement)(scope);
}
};
}
};
});
Working plunkerは下記で入手可能です。 http://plnkr.co/edit/Q13bUt?p=preview
または
angular.module('app')
.directive('commonThings', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true,
priority: 1000,
link: function link(scope,element, attrs) {
element.attr('tooltip', '{{dt()}}');
element.attr('tooltip-placement', 'bottom');
element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html
$compile(element)(scope);
}
};
});
を設定しなければならない理由を説明します。
terminal: true
と
priority: 1000
(が多い)。
DOM の準備ができると、angular は DOM を走査して登録されたすべてのディレクティブを識別し、ディレクティブをひとつずつ
priority
これらのディレクティブが同じ要素にある場合
. カスタムディレクティブの優先度を高くして、確実にコンパイルされるようにします。
最初
と共に
terminal: true
となり、他のディレクティブは
スキップ
このディレクティブがコンパイルされた後に
カスタムディレクティブがコンパイルされると、ディレクティブを追加したり自分自身を削除したりして要素を変更し、$compile サービスを使用して すべてのディレクティブをコンパイルする (スキップされたものも含む) .
を設定しない場合は
terminal:true
と
priority: 1000
の場合、いくつかのディレクティブがコンパイルされる可能性があります。
前に
カスタムディレクティブの そして、カスタムディレクティブが $compile を使って要素 => をコンパイルするとき、すでにコンパイルされているディレクティブを再びコンパイルしてしまいます。これは、特にカスタムディレクティブの前にコンパイルされたディレクティブがすでに DOM を変換している場合、予測不可能な動作を引き起こします。
優先順位と端末の詳細については、以下を参照してください。 ディレクティブの `terminal` を理解するには?
テンプレートも修正するディレクティブの例は、次のとおりです。
ng-repeat
(優先度 = 1000) の場合
ng-repeat
がコンパイルされます。
ng-repeat
他のディレクティブが適用される前に、テンプレート要素のコピーを作成します。
.
Izhaki さんのコメントのおかげで、以下が参考になりました。
ngRepeat
のソースコードです。
https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js
関連
-
WeChatアプレット用ユニアプリによるグローバルシェアリング
-
Vueのフォームイベントのデータバインディングの説明
-
[解決済み】SyntaxError: JSONの位置1に予期しないトークンoがある。
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] jQueryでテーブルの行を追加する
-
[解決済み] AngularJSでデータバインディングはどのように機能するのですか?
-
[解決済み] AngularJSを使用して、ブラウザのコンソールで$scope変数にアクセスするにはどうすればよいですか?
-
[解決済み】AngularJSのディレクティブスコープにおける「@」と「=」の違いは何ですか?
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
-
[解決済み】AngularJSで属性を条件付きで適用するための最良の方法は何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
fetch ネットワークリクエストラッパーの説明例
-
vue+webrtc(Tencent cloud)ライブ機能の実践を実現するために
-
vueディレクティブv-bindの使用と注意点
-
Vueの「データを聴く」原則を解説
-
[解決済み】Node.jsで "Cannot find module "エラーを解決するには?
-
[解決済み] TypeError: $.ajax(...) is not a function?
-
[解決済み】(Google Map API) Geocodeは以下の理由で成功しませんでした。REQUEST_DENIED
-
[解決済み】ReactJSでエラー発生 Uncaught TypeError: Super expression は null か関数でなければならず、undefined ではありません。
-
JSクリックイベント - Uncaught TypeError: プロパティ 'onclick' に null を設定できません。
-
JavaScriptのgetElementById()メソッド入門