[英]AngularDart custom filter call() method required to be idempotent?
Angular Dart教程的主要運行示例是Recipe Book應用程序 。 suggests trying to " " thus allowing a " ." 關於的第5章末尾的練習建議嘗試“ ”,從而允許“ 。“ 例如,當加倍時,“1/2杯面粉”的成分將成為“1杯面粉”。
我寫了這樣一個自定義過濾器:它需要一個Ingredient
列表(由quantity
和description
)並返回一個新的Ingredient
列表(增加數量),但我收到以下錯誤:
5 $digest() iterations reached. Aborting!
我的問題是: AngularDart自定義過濾器call()
方法的必需和/或允許行為是什么? 例如,顯然允許從其輸入列表中刪除(即過濾)元素,但是它是否還可以添加新元素或替換元素? Dart angular.core NgFilter文檔簡單地說“過濾器是一個帶調用方法的類”。 我還沒有找到更多細節。
從AngularJS帖子的答案推斷,似乎重復調用call()
應該(最終?)產生“相同的結果”。 如果是這樣,這將是一個合理的約束。
產生“相同的結果”可能意味着call()
需要是冪等的 ,但在Dart的情況下,這種冪等性應該相對於==
(對象等價)不identical()
(對象身份),恕我直言。 我使用以下小例子運行了一些測試來說明問題:
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());
<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中的第二個call()
實現(帶有add(new A())
那個)仍然會產生錯誤(盡管是另一個錯誤)。
我可以看到如何在不使用自定義過濾器的情況下解決教程練習,但我試圖不放棄尋找可按要求工作的過濾器的挑戰。 我是Angular的新手,決定加入AngularDart,所以任何幫助都可以解釋各種各樣的call()
,或者找到有關call()
的預期行為的文檔,(或者讓我知道你是否認為這樣的自定義過濾器根本無法寫入!)將不勝感激。
當角度檢測到模型中的變化時,它執行反應功能。 反應函數可以進一步改變模型。 這會使模型處於不一致狀態。 出於這個原因,我們重新運行更改檢測,這可以進一步創建更多更改。 因此,我們會繼續重新運行更改,直到模型穩定下來。 但是在放棄之前我們應該多少次重新檢查變化檢測? 默認情況下是5次。 如果模型在5次迭代后沒有穩定,我們放棄。 這就是你的情況。
什么時候改變了對象? 一個人可以使用identical
或==
(等於)。 可以為每個人提供良好的論據,但我們選擇使用identical
因為它快速且一致。 使用==
(等於)是棘手的,它會對變化檢測算法產生負面影響。
當一個操作數組的過濾器執行它時別無選擇,只能創建一個新的數組實例。 這打破了相同的,但幸運的是它被送入ng-repeat
,它使用自己的算法進行數組內容檢測而不是數組檢測。 雖然陣列在運行之間不必相同,但其內容必須是。 否則ng-repeat
無法分辨插入和更改之間的區別,它需要做適當的動畫。
過濾器的問題是它在摘要循環的每次迭代中創建新實例。 這些新實例會阻止模型穩定並因此導致錯誤。 (有計划解決這個問題,但是在我們到達那里之前幾周。)
您的解決方案正在嘗試創建一個消耗整個陣列的過濾器,然后嘗試為ng-repeat
創建一個新陣列。 一個不同的(首選)解決方案是按原樣保留ng-repeat
迭代,而是將過濾器放在創建數量的綁定上並將其應用於那里。
<span>{{recipe.qty | myFilter:multiply}}</span>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.