關於angular在指令中無法獲取子元素的問題?
首先,指令selector-child以屬性的方式在div元素中
& &我是沒有任何指令的&
&{{aa.text}}&
myApp.directive("selectorChild", function () {
return { restrict: "A", link: function (scope,element,attr) { console.log(element.find(".testClass"));// 可以找到沒有任何指令的子元素-&>輸出結果[div.testClass]
console.log(element.find(".listClass")); // 在有ng-repeat指令的子元素卻找不到,結果為空 } };});
蟹妖。
因為在一個directive被link的時候,其內部的directive,是還沒有被執行的。
對於ng-model這類的directive還好,那個元素是還在的。而對於ng-repeat而言則不一樣,為了優化,讓ng-repeat只被compile一次,它會在compile階段把這個節點摘除掉,單獨compile一次,然後在發生數據綁定的時候對每個實例單獨進行link。
用樓上同學的$timeout大法的確是可以的,不過個人不是很建議,因為這樣就變成單次綁定了。
你這樣獲取子元素對於angular來說是非常不建議的,身為一個男人,你必須對ng-repeat的後果負責(霧),它是動態綁定的,意味著它裡面的內容會變,如果你只獲取一次,那它變了,你沒響應,就是不負責任的表現。另一個,你的父directive里對其內容有依賴,這是非常糟糕的實踐。angular給你了一個監聽變化的機會,是通過對數據變化的監聽。其實是可行的,但是我也不建議這麼用。一是在$watch當中你需要維護一個元素它是新的還是舊的,比如避免重複綁事件。二是這樣對於$scope里的數據欄位結構依然是耦合的,而且也沒有解決DOM結構依賴的問題,你的父directive還是沒有復用性可言。
所以個人建議如果一個directive是作為容器,那麼它不應該對任何它的內容有依賴。如果是作為裝飾者,應只作用於元素本身,而不作用於其子元素。
那麼如果想實現一個輪播圖slides怎麼辦?很明顯slides的內容是很適合通過ng-repeat動態綁定的,我現在希望如果定義一個slides組件,它的內容就會被以輪播圖的形式展現。這時候很明顯是組件對其內容有依賴。
這裡參考angular-ui-bootstrap當中的tabset實現舉個例子:再定義一個名為slide-item的directive,在它的聲明當中require: "^slides",這樣變成了子組件依賴父組件。在slides當中定義add, remove, select等API,在slide-item被link的時候調用其父的add來修改數據,並且再通過轉交transclude函數的方式把自己的內容交給slides來處理。這樣做到了:1、slides可以動態包含任意多的slide-item2、slide-item可以transclude任意的內容從依賴關係上看,slide-item依賴slides完全沒問題,聲明了require還能在compile階段得到angular的保護。slides要求其子元素必須用slide-item進行一次(幾乎是透明的)包裝,換來的是完全的動態綁定,也可以接受。與此同時,每一個slide-item只會被link一次,還能避免$watch的重複綁定事件這類問題,在它被transclude的時候讀取它的DOM內容也是可行的。(不過我還是要吐槽一下ui-bootstrap的tabset實現,因為為了最終用戶代碼簡潔,生成的最終DOM結構和組件樹相差甚遠,中間transclude來transclude去的,不過也是為了將就bootstrap)。總之,對於構建一套組件而言:子組件可以依賴父組件,父組件不要依賴子組件寧願依賴數據,不要依賴DOM寧願依賴結構,不要依賴內容因為 selector-child 指令在執行的時候,ng-repeat 還沒有執行,所以找不到任何元素,使用
$timeout(function(){
console.log(element.find(".listClass"));
});
selectorChild全部小寫…
既然想使用ng-repeat,就應該儘可能使用ng的數據綁定能力來實現Dom元素的生成,不要直接操作Dom元素。大多數時候,ng提供的directive有足夠強大的能力操作DOM,建議好好學習一下:ng-class, ng-attr等
推薦閱讀:
※jQuery 和 YUI (Yahoo User Interface) 各自的優缺點有哪些?具體的使用場景是怎樣的?
※有一千本以上實體紙質編程書是什麼體驗?
※NPM中將函數當作一個包發布的方式是否合理?
※如何使用正則表達式得到一個 URL 中的主域名,不用正則還有什麼方法?
TAG:JavaScript | AngularJS |