成熟丰满熟妇高潮XXXXX,人妻无码AV中文系列久久兔费 ,国产精品一国产精品,国精品午夜福利视频不卡麻豆

您好,歡迎來到九壹網(wǎng)。
搜索
您的當前位置:首頁angularJs關于指令的一些冷門屬性詳解

angularJs關于指令的一些冷門屬性詳解

來源:九壹網(wǎng)
我們使用ng的時候,經(jīng)常會使用到指令,大家所熟知的屬性我在這里就不介紹了,講講大家沒怎么留意的屬性

1.multiElement

這是指定指令作用區(qū)間的功能,最常用的就是ng-repeat-start和ng-repeat-end了。

2.priority

指令優(yōu)先級,優(yōu)先級越高,指令越早執(zhí)行。

3.terminal

是否允許優(yōu)先級低的指令起作用,如果是true,那么只有比當前指令或跟當前指令等級相同的指令才可以執(zhí)行。最典型的就是ngIf

4.templateNamespace

聲明模板的格式有三種選擇 svg、html、math

5.transclude

或許有人疑問了,transclude也算是冷門屬性嗎?其實大家對transclude了解并沒有想象的那么深,transclude是一個挺復雜的屬性,一般大家會用到的也僅僅是true,false。這兩個屬性我在這里就不講了,在這里我主要講的是transclude:element,我google了一整天都沒找到正確描述這個屬性的方法。我覺得google出來的答案太文檔化了。最后在研究$transclude才看出來這個屬性的功能究竟在哪里。再講功能前我們先了解下$transclude

無論在指令的compile還是link時期我們的最后一個參數(shù)就是$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);
 }
 }

還有一個另一個函數(shù)要特別指出來,就是最后返回的 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
 });
 }

這兩個方法到底是在做什么呢?其實就是克隆了當前指令的節(jié)點,并生成子作用域??寺〉墓?jié)點由transclude定義,如果你的屬性是true,則克隆的是指令模板中的ng-transclude所在的DOM節(jié)點,及其子節(jié)點。如果屬性是element則克隆整個模板的節(jié)點。

這是兩個指令的代碼

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);
 })
 }
 }
 })

如果你覺得replace干擾了對結果的理解,你可以注釋掉,然后查看控制臺中打印出來的clone,你就能知道所謂transclude的屬性聲明為element的作用了,我們打開replace目的在于能較清楚的查看DOM節(jié)點,來獲得結論,下面就是兩者編譯后DOM節(jié)點的區(qū)別了

201611011003251.png

看完上面的圖,你可以明顯的區(qū)別到兩者對DOM的克隆不一樣的,另外如果在聲明屬性為‘element'時,需要聲明replace為true,才能渲染出來。我查了很多資料,最終用斷點得出了我認為對的結論,斷點追蹤的結果是發(fā)現(xiàn)如果不聲明replace,好像就不會執(zhí)行ngTransclude指令,這點我很奇怪,正因為這樣子所以導致沒有成功渲染。二歸根結底其實是兩者的操作的DOM元素不同,在聲明transclude為element時,replace為true,你取到的DOM節(jié)點是含有transclude屬性的節(jié)點(子節(jié)點),而為false你拿到的并不是含有transclude屬性的節(jié)點(父節(jié)點),而ng本身不對其節(jié)點進行遍歷,導致沒能執(zhí)行ngTransclude指令

我看到一個觀點覺得不錯,大概意思就是:源于功能的考慮,在使用element屬性的時候,一般都是起占位符的作用,你需要做的操作是對DOM的添加時候,才會用到這個克隆功能。

我覺得這個觀點不錯,看過很多關于ngrepeat的介紹,很多文章都說ngrepeat源碼是通過$scope.$new()來生成子作用域的,實際上并不完全正確,他的確是通過$scope.$new產(chǎn)生子作用域的,但是這個產(chǎn)生功能是交給$transclude函數(shù)去做得,實際上ngrepeat的源碼上是通過$transclude來生成子作用域和添加DOM節(jié)點的。與上面的觀點有相似之處。

Copyright ? 2019- 91gzw.com 版權所有 湘ICP備2023023988號-2

違法及侵權請聯(lián)系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市萬商天勤律師事務所王興未律師提供法律服務