2014-01-24 56 views
3

角飛鏢教程的主要運行示例是食譜書應用程序Chapter 5 on filters and services結束時的練習建議嘗試「創建一個[定製]過濾器,該過濾器將乘以配方」中所列每個成分的所有數量「,從而允許」「用戶使用該過濾器的兩倍,三倍或四倍配方「。例如。當「1/2杯麪粉」的成分加倍時將變成「1杯麪粉」。AngularDart自定義過濾器調用()方法需要是冪等的嗎?

我已經寫了這樣一個自定義過濾器:它需要的Ingredient S(包括一個quantitydescription)的列表,並返回新Ingredient個新的列表(增加量),但我得到了以下錯誤:

5 $digest() iterations reached. Aborting! 

我的問題是:什麼是AngularDart自定義過濾器call()方法的要求和/或允許的行爲?例如,顯然允許從其輸入列表中刪除(即過濾)元素,但它是否也可以添加新元素或替換元素? Dart的angular.core NgFilter文檔只是說「過濾器是一個帶有調用方法的類」。我還沒有找到更多的細節。

this AngularJS post的答案推斷,似乎重複調用call()應該(最終?)產生「相同的結果」。如果是這樣,這將是一個合理的限制。

屈服「相同的結果」可能意味着call()需要是冪等,但在這樣的達特冪等的情況下,應該相對於==(對象等價)不identical()(對象標識),IMHO。我使用下面的小例子來說明問題,跑了幾個測試:

  • main.dart
import 'package:angular/angular.dart'; 

    class A { } 

    @NgFilter(name:'myFilter') class MutatingCustomFilter { 
     final A _a = new A(); 
     call(List list) => new List.from(list)..add(_a); // runs ok. 
     // call(List list) => new List.from(list)..add(new A()); // gives error 
    } 

    class MyAppModule extends Module { 
     MyAppModule() { type(MutatingCustomFilter); } 
    } 

    main() => ngBootstrap(module: new MyAppModule()); 
  • index.html的摘錄
<ul> 
     <li ng-repeat="x in [1,2,3] | myFilter">{{x}}</li> 
    </ul> 

如果我將class A的主體更改爲

@override bool operator==(other) => true; 
@override int get hashCode => 1; 

這使得A考慮==所有情況下,那麼在main.dart(具有add(new A()))第二實施call()仍然給出了一個錯誤(雖然不同的一個)。

我可以看到如何在不使用自定義過濾器的情況下解決教程練習,但我試圖不放棄尋找將按要求工作的過濾器的挑戰。我是Angular的新手,決定加入AngularDart,所以在解釋call()各種風格的影響方面有所幫助,或者爲call()的預期行爲尋找文檔,(或者讓我知道你是否認爲這樣的自定義過濾器根本不能寫!)將不勝感激。

回答

5

太多迭代

當角度檢測模型中的一個變化時,它執行一個響應功能。反應功能可以進一步改變模型。這會使模型處於不一致的狀態。出於這個原因,我們重新運行變更檢測,這可以進一步創造更多的變化。出於這個原因,我們不斷重新運行變化,直到模型穩定。但是在放棄之前我們應該多少次重新運行變化檢測?默認情況下是5次。如果模型在5次迭代後不穩定,我們放棄。這是你的情況。

變化檢測

何時有對象改變?可以使用identical==(等於)。每個人都可以提出良好的論據,但我們選擇使用identical,因爲它快速且一致。使用==(等於)很棘手,會對變化檢測算法產生負面影響。

過濾器和陣列

當其操作的陣列的過濾器,執行它別無選擇,只能創建陣列的新實例。這打破了相同的,但幸運的是,它被送入ng-repeat,它使用自己的算法進行數組內容檢測,而不是數組檢測。雖然數組在運行之間不必相同,但它的內容必須是。否則ng-repeat無法分辨插入和更改之間的區別,它需要做適當的動畫。

您的代碼

的問題與你的過濾器,它在消化循環的每個迭代創建新實例。這些新的實例阻止模型穩定,從而導致錯誤。 (有計劃來解決這個問題,但是這將是幾個星期前,我們到達那裏。)

解決方案

你的解決方案,試圖創建一個過濾器消耗了整個數組,然後嘗試創建一個新的數組,爲ng-repeat。一個不同的(首選)解決方案是按原樣保留迭代,並將過濾器放在創建數量的綁定上並應用到那裏。

<span>{{recipe.qty | myFilter:multiply}}</span> 
+0

感謝您對Misko的詳細回覆。我期待更多地瞭解「解決這個問題的計劃」。 –

+0

根據您的反饋,我收集到建議的解決方案只有在'myFilter'是冪等w.r.t.相同(或更準確地說,在5次迭代內收斂)。這似乎是'數字'的情況。在一個成分'quantity'的類型是一個特殊的數字類的實現中,比如說'Rational',支持像'1 1/3'這樣的數字的整數處理(例如「1 1/3杯麪粉」),那麼?這樣的基於過濾器的解決辦法還是不行(模看中實習)還是我失去了一些東西 –

+0

直到「計劃來解決這個問題」的執行,我已經找到了解決辦法:管成分值成(自定義) 'toString'過濾器。 –