3

Angular Dart チュートリアルの主な実行例は、レシピ ブック アプリですフィルターとサービスに関する第 5 章の最後にある演習では、"レシピに記載されている [各材料の] すべての量を乗算する [カスタム] フィルターを作成し、"ユーザーが 2 倍、3 倍、または"レシピを 4 倍にします。」たとえば、「小麦粉 1/2 カップ」の材料は、2 倍にすると「小麦粉 1 カップ」になります。

私はそのようなカスタム フィルターを作成しました: s のリスト( aと aIngredientで構成される) を受け取り、新しい s の新しいリスト(数量を増やしたもの) を返しますが、次のエラーが発生します。quantitydescriptionIngredient

5 $digest() iterations reached. Aborting!

私の質問は: AngularDart カスタム フィルターcall()メソッドの必須および/または許可された動作は何ですか? たとえば、入力リストから要素を削除 (つまり、フィルター) することは明らかに許可されていますが、新しい要素を追加したり、要素を置き換えたりすることはできますか? Dart angular.core NgFilterのドキュメントには、単に「フィルターは呼び出しメソッドを持つクラスである」と書かれています。詳細は見つかりませんでした。

この AngularJS postへの回答から推定すると、(最終的には?) shouldを繰り返し呼び出してもcall()「同じ結果」が得られるように思われます。もしそうなら、これは合理的な制約になります。

「同じ結果」をもたらすことは、べき等である必要があることを意味する可能性call()がありますが、Dart の場合、そのようなべき等性は、 (オブジェクトの同一性) ではなく (オブジェクトの等価性)に関連する必要があります。問題を説明するために、次の小さな例を使用していくつかのテストを実行しました。==identical()

  • 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==の 2 番目の実装 ( を含むもの) では、(別のものではありますが) それでもエラーが発生します。call()add(new A())

カスタム フィルターを使用せずにチュートリアルの演習を解決する方法はわかりますが、要求どおりに機能するフィルターを見つけるという課題をあきらめないようにしています。私は Angular を初めて使用するので、AngularDart を使用することにしました。そのため、 のさまざまなフレーバーの効果を説明しcall()たり、 の予想される動作に関するドキュメントを見つけたりするのに役立ちますcall()(または、そのようなカスタム フィルターが単純にできないと思われる場合はお知らせください)。書いてください!) よろしくお願いします。

4

1 に答える 1

5

繰り返しが多すぎる

angular がモデルの変更を検出すると、リアクション関数を実行します。リアクション機能により、モデルをさらに変更することができます。これにより、モデルが一貫性のない状態になります。このため、変更検出を再実行します。これにより、さらに多くの変更が作成される可能性があります。このため、モデルが安定するまで変更を繰り返します。しかし、あきらめる前に変更検出を何回再実行する必要があるでしょうか? デフォルトでは 5 回です。5 回繰り返してもモデルが安定しない場合は、あきらめます。これがあなたの場合に起こっていることです。

変更検出

オブジェクトはいつ変更されましたか? identicalor ==(equals)を使用できます。それぞれについて適切な議論を行うことができますが、identical高速で一貫性があるため、使用することにしました。(equals) の使用==はトリッキーであり、変更検出アルゴリズムに悪影響を及ぼします。

フィルターと配列

配列を操作するフィルターが実行されると、配列の新しいインスタンスを作成するしかありません。これは同じように壊れますが、幸いなことにng-repeat、配列の検出ではなく、配列の内容の検出に独自のアルゴリズムを使用するものにフィードされます。配列は実行間で同一である必要はありませんが、その内容は同一でなければなりません。そうng-repeatしないと、適切なアニメーションを実行するために必要な挿入と変更の違いを判断できません。

あなたのコード

フィルターの問題は、ダイジェスト ループの反復ごとに新しいインスタンスが作成されることです。これらの新しいインスタンスにより、モデルが安定しなくなり、エラーが発生します。(この問題を解決する計画はありますが、そこに到達するまでには数週間かかります。)

解決

あなたのソリューションは、配列全体を消費してから新しい配列を作成しようとするフィルターを作成しようとしていますng-repeat。別の (推奨される) 解決策は、ng-repeat反復をそのままにしておき、代わりに、qty を作成しているバインディングにフィルターを配置して、そこに適用することです。

<span>{{recipe.qty | myFilter:multiply}}</span>
于 2014-01-27T04:48:51.280 に答える