web-dev-qa-db-ja.com

Angular2:配列が更新されても* ngForは更新されません

オブジェクトの配列があります(arrと呼びましょう)。 _(change)_メソッドでのコンポーネントの入力の1つで、これらのオブジェクトの属性の1つを変更しますが、ビュー(_*ngFor_)では何も変わりません。 Angular2の変更検出では配列やオブジェクトの内容をチェックしないことを読んだので、これらを試しました

_this.arr = this.arr.slice();
_

そして

_this.arr = [...this.arr];
_

ただし、ビューは変更されず、古い属性が引き続き表示されます。 console.log()を含む_(change)_メソッドで、正しい配列を取得しました。奇妙ですが、これはうまくいきます:_this.arr = [];_私もNgZonemarkForCheck()を試しました。

15
Roland Rácz

してディープコピーを作成してみてください

this.arr = Object.assign({}, NEW_VALUE);
2
Eun Leem

_*ngFor_式でtrackByオプションを使用して、配列内のすべての項目に一意のIDを提供することもできます。これにより、変更の検出が100%行われるため、配列のアイテムが変更されるたびにこの(一意の)プロパティを更新します。 Angularは、配列内のアイテムに異なるtrackByプロパティが与えられた場合にのみリストを再レンダリングします

*ngFor="let item of (itemList$ | async); trackBy: trackItem"

または:

_*ngFor="let item of itemList; trackBy: trackItem"_

ここで:

trackItemはコンポーネントのパブリックメソッドです。

_public trackItem (index: number, item: Item) {
  return item.trackId;
}
_
6
Michael Trouw
  1. コンポーネントがchangeDetection:cHangeDetectionStrategy.OnPushで設定されているかどうかを確認します。これを行う場合は、配列の更新後にchangeDetectorRef.markForCheck()を呼び出す必要があります。
  2. OnChangeライフサイクルフックを実装し、この関数内で配列の値を変更することもできます。
3
Rohan Fating

既にmarkForCheck()を試したと述べたので、代わりにdetectChangesを試してください(私にとってはうまくいき、markForCheckはうまくいきませんでした)。手順が必要な場合:

ChangeDetectorRefをインポートに追加します。

import { Component, OnInit, ChangeDetectorRef } from '@angular/core';

ChangeDetectorRefをコンストラクタに追加します。

constructor(
    private changeDetection: ChangeDetectorRef
  ) { }

次に、配列を更新した後の次の行で:

this.changeDetection.detectChanges();
2

次のように@componentにchangDetectionディレクティブを追加して、このエラーを解決しました

    @Component({
      selector: 'app-page',
      templateUrl: './page.component.html',
      styleUrls: ['./page.component.scss'],
      changeDetection: ChangeDetectionStrategy.Default
    })

また、それをインポートする必要があります

import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';

OnPushとDefaultの2つの戦略があります

OnPushはCheckOnceストラテジーを使用します。つまり、ストラテジーをデフォルト(CheckAlways)に設定して再アクティブ化するまで、自動変更検出は非アクティブ化されます。変更検出は明示的に呼び出すことができます。

デフォルトはCheckAlways戦略を使用します。この戦略では、変更の検出は明示的に無効になるまで自動的に行われます。

ソース ドキュメント

1
Felix Runye

他の誰かが私の状況に陥った場合、更新しているコンポーネントがレンダリングされているコンポーネントと同じであることを確認してください。

私は@ViewChild(MyComponent, { static: true }) private test: MyComponentを使用して、ngforでデータをコンポーネントに渡していました。 (私の場合、私は知らなかった別のコピーにロックされました)

HTMLのコンポーネントタグに属性_#mycomp_を追加し、上記を@ViewChild('mycomp', { static: true }) private test: MyComponentに変更することで修正できました。

0
Tezra