2014-02-18 37 views
2

我有一個簡單的使用AngularJS創建的數據表。表中的一列是根據控制器上的功能計算出來的。在Angular + UI中創建獨立範圍的問題引導

我打開一個新的模式在網頁上的按鈕。當我使用UI引導打開一個模式時,如預期的那樣,我得到一個新的獨立範圍(根範圍的子節點)。但是,如果我在模式中有輸入文本,則在此文本字段中的任何按鍵都會自動調用父範圍上的函數 - 即使我可以驗證範圍是否被隔離。

這裏是行爲的plunkr:http://plnkr.co/edit/JzhxSDcSefDe04Psxq0w

如該示例中所示,表的第三列與一個名爲「ageNextYear」函數來計算。當表格被渲染時,這個函數被調用多次(可以在控制檯日誌中驗證)。但是,如果打開模式並在該字段中鍵入一些文本,則父級作用域上的「ageNextYear」函數仍會被調用(在輸入字段中鍵入一些文本並查看控制檯日誌輸出)。

我不知道這是否是預期的行爲,或者我是否做錯了什麼。我已經嘗試在兩個作用域上使用點符號,並明確地將新作用域傳遞給$ modal.open,但沒有喜悅。

我可以解決這個問題(通過創建一個關於「人」的watchCollection並以這種方式更新表 - 這可能是一個更好的方式來做這個),但是想驗證其他人是否也看到了這種行爲。

+0

是否有可能你的問題與指令modalWindow使用'transclude'的事實有關嗎? – koolunix

回答

3

您所遇到的問題是不相關的模式對話框的範圍。這個問題與在ng-repeat表達式中使用函數有關。一般來說,在表達式中使用函數是一個性能問題,但在ng-repeat中這是一個更大的問題。根據這對於common pitfalls of using scopes優秀的文章,

當使用的意見或觀察表達式,你應該永遠記住,一個表達式被稱爲認爲它是需要每次AngularJS。使用函數不會獲得最佳性能,您甚至可能會錯過一些更改事件。

這意味着表達...

  1. 一個NG-重複內將被稱爲用於單獨的每個項目。此外,重複指令使用此來確定數據更改。
  2. 可以在一個摘要中多次評估。當您使用多個指令或其他示波器監視器時,可能會發生這種情況。
  3. 即使直接作用域看起來不變,也可以進行評估。
  4. 如果函數的返回值發生變化,則僅在函數定義發生更改時纔會評估包含函數。

你的示例將導致這些4 3發生。

  1. 您重複對作用域中每個對象的函數調用,3項= 3調用該函數。
  2. 您可以通過調用模態對話框間接添加一個觀察器。
  3. 模態對話框範圍內的數據更改會導致評估包含ng-repeat的控制器的範圍,即使ng-repeat內的數據沒有變化(無法知道數據是否更改直到$ digest被調用)。對Modal的每次更改都會導致$ digest,這會導致另一次通過ng-repeat,而另一次調用ng-repeat中的每個項目。

在你的情況下,邏輯並不需要運行每一個表達式將被評估的時間。邏輯結果發生變化時,最好計算邏輯並將其寫入範圍。這將邏輯從對象和視圖中分離出來。

總之,

最佳實踐:

  • 不要使用函數表達式。
  • 請勿在表達式中使用範圍以外的其他數據。
  • 當應用外部數據更改時,請使用$ scope。$ apply()。
+0

謝謝,安德魯 - 這是一個有用的文檔。我很好奇 - 如果你要重寫這個掠奪者的例子,以避免你提到的3件東西,它會是什麼樣子?你會使用WatchCollection還是其他策略? –

+0

我不建議在這種情況下使用WatchCollection,因爲它不會監視集合中的深層變化。相反,使用$ watch替代語法'$ watch(collection,[Equality = true])''。在我的備用http://plnkr.co/edit/FQZwbx3jkQ3B5xp7izvG?p=preview中,您可以看到更改何時開始。請參閱http://www.bennadel.com/blog/2566-Scope-watch-vs-watchCollection-In-AngularJS.htm瞭解更多關於watch vs watchCollection – Claies

+0

還注意到,如果我正在爲此進行製作,我會額外做檢查比較手錶中的'oldVal'和'newVal',進一步優化更新調用 – Claies

1

西蒙, 我喜歡你的問題,我說手錶的範圍和看見消化的週期也越來越稱爲

$範圍。$表(功能watchMe(範圍){執行console.log(文摘「看着我!');});

以下是摘要分支。 http://plnkr.co/edit/5PTO1uPFvmLrg7K9vzTm?p=preview

我不知道這是原因,但我認爲ng-repeat內部的表達式調用摘要,因爲它試圖評估該項目上任何事件的表達式。

我認爲我們應該評估模型中的表達,並給更新的模型到NG-重複,以解決這一問題。