私がこのことについて質問するのは初めてではないことは承知していますが、以前の質問では答えが見つかりませんでした。私はこれを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
コンポーネントは、ngOnChanges
Google マップ上のマーカーを再描画するためのトリガーとして使用する必要があります。問題は、親が変更された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();
}
アップデート: ngOnChanges
lapsData
は動作していませんが、更新されているように見えます。 には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 つあります。
ngDoCheck()
配列の内容が変更されたかどうかを判断するために、独自の変更検出ロジックを実装して実行します。(ライフサイクルフックのドキュメントには例。rawLapsData
配列の内容に変更を加えるたびに、新しい配列を割り当てます。その後ngOnChanges()
、配列 (参照) が変更されたため、 が呼び出されます。
あなたの答えでは、別の解決策が見つかりました。
ここで OP に関するコメントをいくつか繰り返します:
laps
が変更を検出できるngOnChanges()
のに (それ自身と同等のものを使用しているはず)、それmap
ができない理由がまだわかりません。
- コンポーネントでは、
laps
コード/テンプレートがlapsData
配列内の各エントリをループし、その内容を表示するため、表示されるデータの各部分に Angular バインディングが存在します。 - Angular がコンポーネントの入力プロパティの変更を検出しない場合でも (
===
チェックを使用)、すべてのテンプレート バインディングを (デフォルトで) ダーティ チェックします。これらのいずれかが変更されると、Angular は DOM を更新します。これが表示されているものです。 - おそらく、コンポーネント
maps
のテンプレートには入力プロパティへのバインディングがないのではないlapsData
でしょうか。それが違いの理由でしょう。
lapsData
両方のコンポーネントとrawLapsData
親コンポーネントで、すべてが同じ/1 つの配列を指していることに注意してください。したがってlapsData
、Angular は入力プロパティへの (参照) 変更を認識しませんが、コンポーネントはすべてその 1 つの配列を共有/参照するため、配列の内容の変更を「取得」/確認します。プリミティブ型 (文字列、数値、ブール値) の場合のように、これらの変更を伝播するために Angular は必要ありません。ただし、プリミティブ型では、値の変更は常にトリガーされますngOnChanges()
。これは、回答/ソリューションで活用されているものです。
おそらくすでにお分かりかと思いますが、オブジェクト入力プロパティは配列入力プロパティと同じ動作をします。