ホームページ > 記事 > ウェブフロントエンド > angularJs のディレクティブの不人気な属性の詳細な説明
NG を使用する場合、よく知られている属性についてはここでは紹介しません
1.multiElement
の機能です。命令のスコープを指定するもので、最も一般的に使用されるのは ng-repeat-start と ng-repeat-end です。
2.priority
命令の優先順位。優先順位が高いほど、命令がより早く実行されます。
3.ターミナル
優先度の低い命令の動作を許可するかどうか。true の場合、現在の命令と同じレベル以上の命令のみを実行できます。最も典型的なものは ngIf です
4.templateNamespace
宣言テンプレートの形式には svg、html、math の 3 つのオプションがあります
5.transclude
疑問を持つ人もいるかもしれませんが、transclude も人気のない属性ですか?実際、誰もが思っているほど、transclude についてよく知りません。transclude は非常に複雑な属性です。一般に、誰もが使用するのは true と false だけです。ここではこれら 2 つの属性については説明しません。ここで主に説明するのは、transclude:element についてです。一日中グーグル検索しましたが、この属性を正しく説明する方法が見つかりませんでした。 Google の回答は文書化されすぎていると思います。最後に、$transclude を勉強した後、この属性の機能が何であるかを理解しました。関数について話す前に、まず $transclude を理解しましょう
最後のパラメータは、命令のコンパイル期間またはリンク期間に関係なく、$transclude です。 ここでは、ソース コードがどのように定義されているかを実際に見ていきます。 ng1.5.3
function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement, slotName) { var transcludeControllers; // No scope passed in: if (!isScope(scope)) { slotName = futureParentElement; futureParentElement = cloneAttachFn; cloneAttachFn = scope; scope = undefined; } if (hasElementTranscludeDirective) { transcludeControllers = elementControllers; } if (!futureParentElement) { futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element; } if (slotName) { // slotTranscludeFn can be one of three things: // * a transclude function - a filled slot // * `null` - an optional slot that was not filled // * `undefined` - a slot that was not declared (i.e. invalid) var slotTranscludeFn = boundTranscludeFn.$$slots[slotName]; if (slotTranscludeFn) { return slotTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild); } else if (isUndefined(slotTranscludeFn)) { throw $compileMinErr('noslot', 'No parent directive that requires a transclusion with slot name "{0}". ' + 'Element: {1}', slotName, startingTag($element)); } } else { return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild); } }
特に指摘しなければならない機能がもう1つあり、それは最後に返されるboundTranscludeFnメソッドです。 以下はそのソースコードです
function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) { function boundTranscludeFn(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) { if (!transcludedScope) { transcludedScope = scope.$new(false, containingScope); transcludedScope.$$transcluded = true; } return transcludeFn(transcludedScope, cloneFn, { parentBoundTranscludeFn: previousBoundTranscludeFn, transcludeControllers: controllers, futureParentElement: futureParentElement }); }
この2つのメソッドは何をしているのでしょうか?実際、現在の命令のノードのクローンを作成し、子スコープを生成します。クローン化されたノードは、transclude によって定義されます。属性が true の場合、命令テンプレートの ng-transclude が配置されている DOM ノードとその子ノードがクローン化されます。属性が要素の場合、テンプレート ノード全体のクローンを作成します。
これは 2 つの命令のコードです
angular.module('MyApp', []) .directive('dropPanel', function() { return { transclude: 'element', replace: true, template: "<div class='drop-panel'>" + "<span ng-transclude class='111'></span>" + "</div>", link: function(scope, el, c, d, $transclude) { $transclude(function ngRepeatTransclude(clone, scope) { console.log(clone); }) } } }) .directive('dropPanel2', function() { return { transclude: true, replace: true, template: "<div class='drop-panel'>" + "<span ng-transclude class='111'></span>" + "</div>", link: function(scope, el, c, d, $transclude) { $transclude(function ngRepeatTransclude(clone, scope) { console.log(clone); }) } } })
置換が結果の理解を妨げていると感じる場合は、コメントアウトして、コンソールに出力されたクローンを見ると、その役割を知ることができます。要素として宣言されたいわゆる transclude 属性 ここで、replace を開く目的は、DOM ノードをより明確に表示して結論を導くことです。上の図を読むと、コンパイル後の DOM ノードの違いがわかります。この 2 つは明確に区別されます。また、属性を「要素」として宣言する場合は、レンダリングする前に replace を true として宣言する必要があります。多くの情報を確認し、最終的にブレークポイントを使用して正しい結論に達しました。ブレークポイント追跡の結果、replace が宣言されていない場合、ngTransclude 命令は実行されないようです。このため、レンダリングが失敗します。次に、最終的な分析は、2 つの操作の DOM 要素が異なるということです。transclude を要素として宣言する場合、replace は true であり、取得される DOM ノードは transclude 属性を含むノード (子ノード) であり、それが false の場合です。 , 得られるものはそうではありません。transclude 属性を含むノード (親ノード) であり、ng 自体がそのノードを走査しないため、ngTransclude 命令の実行に失敗します
良いと思う視点を拝見しました。これはおそらく次のことを意味します: 機能上の考慮事項により、要素属性を使用する場合、通常はプレースホルダーとして機能します。このクローン作成関数は、実行する必要がある操作が DOM に追加される場合にのみ使用されます。
この観点は良いと思います。ngrepeat についての多くの紹介文を読んだことがありますが、実際には、これは完全に正しいわけではありません。 use $scope.$new はサブスコープを生成しますが、この生成機能は $transclude 関数に任せられています。実際、ngrepeat のソースコードは $transclude を使用してサブスコープを生成し、DOM ノードを追加します。上記の点と同様です。