web-dev-qa-db-ja.com

AngularJSの「トラックバイ」とは何ですか?

track by動作し、その動作。
私の主な目標は、ng-repeatいくつかの精度を追加します。

18
xoxel

track byを使用して文字列を追跡し、値を複製する

通常、ng-repeatは、各アイテムをアイテム自体で追跡します。指定された配列objs = [ 'one', 'one', 2, 'five', 'string', 'foo']に対して、ng-repeatは、ng-repeat="obj in objs"内の各objによる変更の追跡を試みます。問題は、値が重複しており、angularがエラーをスローすることです。これを解決する1つの方法は、angularに他の手段でオブジェクトを追跡させることです。文字列については、文字列を追跡する他の手段がないため、track by $indexは良い解決策です。

track by&ダイジェストと入力フォーカスのトリガー

あなたは、アンギュラーにやや新しいという事実をほのめかします。ダイジェストサイクルは、対応するビューへの変更を反映するために、angularが各監視対象プロパティの徹底的なチェックを実行するときに発生します。多くの場合、ダイジェストサイクル中に、コードが他の監視対象プロパティを変更するため、angularがそれ以上変更を検出しなくなるまでプロシージャを再度実行する必要があります。

たとえば、ボタンをクリックしてng-clickを介してモデルを更新し、次に何か(つまり、ユーザーがクリックしたときに実行するコールバックで記述したこと)を実行し、angularビューを更新するためにダイジェストサイクルをトリガーします。私はそれを説明するのはあまり明確ではないので、それが物事を明確にしなかった場合は、さらに調査する必要があります。

track byに戻ります。例を使用してみましょう:

  1. サービスを呼び出してオブジェクトの配列を返します
  2. 配列内のオブジェクトを更新し、オブジェクトを保存します
  3. 保存サービスの後、APIが返す内容に応じて、次のことができます。
    1. オブジェクト全体を置き換えるOR
    2. 既存のオブジェクトの値を更新します
  4. ng-repeat UIの変更を反映

このオブジェクトを追跡する方法によって、UIが変更をどのように反映するかが決まります。

私が経験した中で最も迷惑なUXの1つはこれです。オブジェクトのテーブルがあるとします。各セルには、オブジェクトのプロパティをインライン編集する入力があります。値を変更し、on-blurを変更して、応答を待っている間に編集する次のセルに移動しながらそのオブジェクトを保存します。これは自動保存タイプのものです。 track byステートメントの設定方法によっては、応答がオブジェクトの配列に書き戻されると、現在のフォーカス(現在編集中のフィールドなど)が失われる場合があります。

19
jusopi

track byを追加すると、基本的にangularに、指定されたコレクションのデータオブジェクトごとに1つのDOM要素を生成するように伝えます。

データソースに重複した識別子がある場合は、track by $indexできます。

重複するアイテムを繰り返す必要がある場合は、式による追跡を使用して、デフォルトの追跡動作を独自の追跡動作に置き換えることができます。

例:

[{id:1,name:'one'}, {id:1,name:'one too'}, {id:2,name:'two'}]

ng-repeatで重複する値を使用しようとすると、次のようなエラーが表示されます。

エラー:ngRepeat:dupes Duplicate Duplicate Key in Repeater

この種の問題を回避するには、track by $indexを使用する必要があります。例えば:

<ul>
   <li ng-repeat="item in [1, 2, 3, 3] track by $index">
       {{ item }}
   </li>
</ul>

ネストされた$indexng-repeatを取得する方法は次のとおりです。

<div ng-repeat="row in matrix">
    <div ng-repeat="column in row">
      <span>outer: {{$parent.$index}} inner: {{$index}}</span>
    </div>
</div>

役立つリソースをいくつか紹介します。

12
Mohit Tanwani

track byのデフォルトの動作に反する必要がある場合にのみ、ng-repeatを使用する必要があります。これは、重複するアイテムを削除することです。
スコーププロパティ$indexを使用するか、カスタム関数を指定して、アイテムを追跡できます。

例えば:

<div ng-repeat="x in [42, 42, 43, 43] track by $index">
  {{x}}
</div>

配列のすべての値を表示します(42が2回表示されます)。

参考: https://docs.angularjs.org/api/ng/directive/ngRepeat

3
Elio Salvatore