Angular2の変更検出: ネストされたオブジェクトに対してngOnChangesが発動しない 質問する

Angular2の変更検出: ネストされたオブジェクトに対してngOnChangesが発動しない 質問する

私がこのことについて質問するのは初めてではないことは承知していますが、以前の質問では答えが見つかりませんでした。私はこれを1つのコンポーネントで持っています

<div class="col-sm-5">
    <laps
        [lapsData]="rawLapsData"
        [selectedTps]="selectedTps"
        (lapsHandler)="lapsHandler($event)">
    </laps>
</div>

<map
    [lapsData]="rawLapsData"
    class="col-sm-7">
</map>

コントローラーはrawLapsdata時々変更されます。

ではlaps、データはHTML表形式で出力されます。これはrawLapsdata変更されるたびに変更されます。

私のmapコンポーネントは、ngOnChangesGoogle マップ上のマーカーを再描画するためのトリガーとして使用する必要があります。問題は、親が変更されたngOnChangesときに起動されないことですrawLapsData。どうすればよいでしょうか?

import {Component, Input, OnInit, OnChanges, SimpleChange} from 'angular2/core';

@Component({
    selector: 'map',
    templateUrl: './components/edMap/edMap.html',
    styleUrls: ['./components/edMap/edMap.css']
})
export class MapCmp implements OnInit, OnChanges {
    @Input() lapsData: any;
    map: google.maps.Map;

    ngOnInit() {
        ...
    }

    ngOnChanges(changes: { [propName: string]: SimpleChange }) {
        console.log('ngOnChanges = ', changes['lapsData']);
        if (this.map) this.drawMarkers();
    }

アップデート: ngOnChangeslapsDataは動作していませんが、更新されているように見えます。 にはngOnInit、 も呼び出されるズーム変更のイベント リスナーがありますthis.drawmarkers。ズームを変更すると、確かにマーカーが変更されます。したがって、唯一の問題は、入力データが変更されたときに通知が届かないことです。

親には、この行があります。(変更は laps に反映されますが、 には反映されないことに注意してくださいmap)。

this.rawLapsData = deletePoints(this.rawLapsData, this.selectedTps);

そして、this.rawLapsDataそれ自体が大きなJSONオブジェクトの真ん中へのポインタであることに注意してください

this.rawLapsData = this.main.data.TrainingCenterDatabase.Activities[0].Activity[0].Lap;

ベストアンサー1

rawLapsData配列の内容を変更した場合でも (項目の追加、項目の削除、項目の変更など)、同じ配列を指し続けます。

変更検出中に、Angular がコンポーネントの入力プロパティの変更をチェックするときに、(基本的に)===ダーティ チェックを使用します。配列の場合、これは配列参照 (のみ) がダーティ チェックされることを意味します。rawLapsData配列参照は変更されないため、ngOnChanges()は呼び出されません。

考えられる解決策は 2 つあります。

  1. ngDoCheck()配列の内容が変更されたかどうかを判断するために、独自の変更検出ロジックを実装して実行します。(ライフサイクルフックのドキュメントには

  2. rawLapsData配列の内容に変更を加えるたびに、新しい配列を割り当てます。その後ngOnChanges()、配列 (参照) が変更されたため、 が呼び出されます。

あなたの答えでは、別の解決策が見つかりました。

ここで OP に関するコメントをいくつか繰り返します:

lapsが変更を検出できるngOnChanges()のに (それ自身と同等のものを使用しているはず)、それmapができない理由がまだわかりません。

  • コンポーネントでは、lapsコード/テンプレートがlapsData配列内の各エントリをループし、その内容を表示するため、表示されるデータの各部分に Angular バインディングが存在します。
  • Angular がコンポーネントの入力プロパティの変更を検出しない場合でも (===チェックを使用)、すべてのテンプレート バインディングを (デフォルトで) ダーティ チェックします。これらのいずれかが変更されると、Angular は DOM を更新します。これが表示されているものです。
  • おそらく、コンポーネントmapsのテンプレートには入力プロパティへのバインディングがないのではないlapsDataでしょうか。それが違いの理由でしょう。

lapsData両方のコンポーネントとrawLapsData親コンポーネントで、すべてが同じ/1 つの配列を指していることに注意してください。したがってlapsData、Angular は入力プロパティへの (参照) 変更を認識しませんが、コンポーネントはすべてその 1 つの配列を共有/参照するため、配列の内容の変更を「取得」/確認します。プリミティブ型 (文字列、数値、ブール値) の場合のように、これらの変更を伝播するために Angular は必要ありません。ただし、プリミティブ型では、値の変更は常にトリガーされますngOnChanges()。これは、回答/ソリューションで活用されているものです。

おそらくすでにお分かりかと思いますが、オブジェクト入力プロパティは配列入力プロパティと同じ動作をします。

おすすめ記事