2014-08-29 60 views
3

您可能已經聽過很多次了。 「在指令中執行所有的DOM操作」。但似乎沒有人會說如果你真的在Angular的一個指令之外做DOM操作會發生什麼。爲什麼元素在指令的鏈接功能中不可用

我有我設法在這個Plunk

我做了一個非常簡單的指令,只是輸出單元控制檯來重現問題。

app.directive('dirre', function(){ 
    return { 
    link: function(scope, element, attrs){ 
     console.log({message:"dirrens linkFn", element: element, count: element.length}) 
    } 
    } 
}); 

我有兩個相同的jquery UI手風琴,唯一的區別是它們被調用的方式。一個在控制器中調用,另一個在一個指令中調用。從控制器調用手風琴當然是不好的。

正如你可以看到,如果你運行應用程序有一種情況,其中一個dirre指令似乎沒有一個元素,但沒有錯誤。

同樣的事情發生在我現在正在使用的大型應用程序中。問題似乎是我們團隊中的某個人決定在控制器中調用Jquery UI的手風琴,而不是指令。 我還沒有能夠通過代碼來看看實際發生了什麼,但我強烈懷疑在Angular正在編譯時出現DOM被修改,並且出現錯誤。 這是一個合理的解釋嗎?

這是一個例子,如果你在指令之外進行DOM操作會出現什麼問題?

回答

0

控制器和指令鏈接函數是異步調用的。 通常您可以看到在主控制器完成之前構建的指令。當控制器終止時,指令更新他們的監視變量(ngModel,$ watch(something)...)。基本上這是通過承諾完成的。

但是鏈接/編譯功能不會再被調用。你必須編譯,觀察,應用新的DOM。這基本上意味着將相似的代碼寫入到angularjs中。

+0

在我發佈的示例中,顯然有些腥意。該元素在目錄的鏈接函數中不可用,因爲它應該是。我不確定你是否正在回答這個問題。手風琴的DOM操作是否會干擾某些Angular過程? – Edminsson 2014-08-29 12:20:04

+0

我不相信你說的是正確的,當頁面加載角引導本身並編譯通過所有節點並同步執行指令的文檔時,唯一的情況是指令鏈接/編譯函數將被異步調用如果它使用templateUrl來獲取模板。 '$ watch'表達式是在'$ digest'迭代中執行的,它與promise沒有任何關係。要觸發$摘要,必須發生JavaScript事件(用戶單擊某個元素,XHR響應等)。 – Wawy 2014-08-29 16:30:08

+0

您是對的,它的措辭很糟糕。我沒有說鏈接函數是異步的。我的意思是在指令完成之前啓動maint Controller。他們不相關。 #accordion內置於控制器中,因此這些更改不會被指令看到 – 2014-09-08 13:45:01

相關問題