2016-09-20 66 views
3

我有一個指令,執行以下操作:

  1. 將另一個指令屬性的元素。
  2. 刪除自己的屬性。
  3. 調用元素上的$compile()以使AngularJS重新編譯元素,以便附加新指令。

這工作正常,除了我也添加ng-if元素。看到這個最簡單的例子,並按照下面的步驟來演示。

https://embed.plnkr.co/ymk0RwGopGF1KvesWmvA/

  1. +任意次數添加到 「計數」。
  2. 0重置「計數」。
  3. 再次按+任意次數。

我希望在步驟#2之後,一旦其ng-if條件不再成立,我會從DOM中刪除標記以從DOM中刪除。相反,它會停留在周圍,並且在步驟#3後您會看到額外的消息副本。

我假設在my-test指令中調用$compile($element)($scope);鏈接函數有一些意想不到的後果,但我不明白這裏發生了什麼。有任何想法嗎?

謝謝, 大衛

回答

1

正如其他人回答,短期解決方案是使用ng-show而不是ng-if或不使用$compile這樣。除此之外,你可能有你的理由,你爲什麼要這樣使用ng-if$compile

這個問題讓我感興趣的是使用$compile的注意事項,隔離範圍從ng-if。我對this fork做了一些嘗試,並試圖解釋我發現的內容。

我們已經知道ng-if創建隔離範圍,但隨後通過該元素與ng-if它通過$compile創建另一隔離範圍(並會作出新編譯ng-if在看第一輪變量分離範圍 - 該指令的值爲$scope)。

再次重申的是,我們遇到一些範圍看上去像(在[]的值範圍的$ id。):

  1. 主/外控制器具有scope[2]

  2. ng-if my-test元件有ng-if看着scope[2].count並創建因此scope[3]

  3. my-test接頭具有$scope.$id == 3;

  4. my-test確實$compile - 重新編譯ng-if元素:創建新的分離scope[4],並期待在scope[3].count

  5. scope[2].count命中0 - scope[3]得到$destroyed(因爲scope[3]是由第一ng-if創建這仍然是揮之不去在某處)......但是!元素是A.仍在那裏和B.它的計數沒有更新 - 爲什麼?

好,因爲這是該元素還有一個,這是$compiled並具有A.一個ng-if看着scope[3].count(現在$破壞)和B.自己的新菌株scope[4](通過重新編譯創建ng-if元素與父母scope[3]

所以你。這一切都很混亂,你可能會問......我該如何解決這個問題?

TL; DR;

最簡單的辦法: $element.removeAttr('ng-if');之前,你做$compile($element)($scope);

如果你一直在下面,這工作,因爲原來的ng-if仍在尋找在scope[2].count,那就是目前的元素不再是得到一個第二隔離範圍。

+0

這非常有幫助,謝謝。其他內置指令是否創建了一個獨立的作用域,如ng-if?如果我碰巧在我的指令旁邊使用ng-repeat或甚至是定製/第三方指令,我是否可能再次遇到同樣的問題? –

+0

很高興它有幫助!一些內置和第三方指令確實創建了隔離範圍。您只需查看您計劃使用的每條指令的文檔。例如,[ng-if docs](https://docs.angularjs.org/api/ng/directive/ngIf)表示「此指令創建新範圍。」 (在Directive Info部分下)和[ng-repeat docs]一樣(https://docs.angularjs.org/api/ng/directive/ngRepeat),但你會看到[ng-show](https:// docs .angularjs.org/api/ng/directive/ngShow)(例如)不。 – plong0

1

我不知道如何正確地解釋,但NG-如果增加了一個新的範圍元素,他自己的範圍,檢查這個問題,所以看到更多的細節:what is the difference between ng-if and ng-show/ng-hide。我試着用NG-節目和它的工作您想要的方式:

ng-show="count > 0" 

希望它可以幫助=)

2

至於我能理解,當你改變計數的值0,你的指令是在更改count的值之前銷燬。因此,未清除指令的計數值仍然爲1.

如果您使用ngShow而不是ngIf,則可以解決此問題。因爲ngShow屬性不會觸發$ destroy事件並且不會從您的視圖中刪除元素。因此,該指令可以捕獲count的新價值。或者,您可以使用prelink而不是link來獲取count的更新值。

+0

我也發佈之前嘗試過ng-show,我同意它在簡約的例子中解決了這個問題。然而,在我的真實應用程序中,有些情況下需要實際使用ng-if,比如可見時需要的表單輸入。 –

+0

@DavidSmith現在我記得了。您可以使用'prelink'將鏈接屬性重命名。在這個改變之後,你的ngIf將能夠捕獲'count'的值。你可以通過這種方式解決這個問題。 –