1. ホーム
  2. angular

[解決済み] Angular 2 - モデル変更後、ビューが更新されない

2022-05-01 04:02:52

質問

私は、数秒ごとにREST APIを呼び出し、いくつかのJSONデータを受信するシンプルなコンポーネントを持っています。 ログステートメントとネットワークトラフィックから、返されたJSONデータが変化していること、モデルが更新されていることを確認できますが、ビューは変化していません。

私のコンポーネントは次のようなものです。

import {Component, OnInit} from 'angular2/core';
import {RecentDetectionService} from '../services/recentdetection.service';
import {RecentDetection} from '../model/recentdetection';
import {Observable} from 'rxjs/Rx';

@Component({
    selector: 'recent-detections',
    templateUrl: '/app/components/recentdetection.template.html',
    providers: [RecentDetectionService]
})



export class RecentDetectionComponent implements OnInit {

    recentDetections: Array<RecentDetection>;

    constructor(private recentDetectionService: RecentDetectionService) {
        this.recentDetections = new Array<RecentDetection>();
    }

    getRecentDetections(): void {
        this.recentDetectionService.getJsonFromApi()
            .subscribe(recent => { this.recentDetections = recent;
             console.log(this.recentDetections[0].macAddress) });
    }

    ngOnInit() {
        this.getRecentDetections();
        let timer = Observable.timer(2000, 5000);
        timer.subscribe(() => this.getRecentDetections());
    }
}

そして、私のビューは次のようになります。

<div class="panel panel-default">
    <!-- Default panel contents -->
    <div class="panel-heading"><h3>Recently detected</h3></div>
    <div class="panel-body">
        <p>Recently detected devices</p>
    </div>

    <!-- Table -->
    <table class="table" style="table-layout: fixed;  word-wrap: break-word;">
        <thead>
            <tr>
                <th>Id</th>
                <th>Vendor</th>
                <th>Time</th>
                <th>Mac</th>
            </tr>
        </thead>
        <tbody  >
            <tr *ngFor="#detected of recentDetections">
                <td>{{detected.broadcastId}}</td>
                <td>{{detected.vendor}}</td>
                <td>{{detected.timeStamp | date:'yyyy-MM-dd HH:mm:ss'}}</td>
                <td>{{detected.macAddress}}</td>
            </tr>
        </tbody>
    </table>
</div>

の結果からわかるのですが console.log(this.recentDetections[0].macAddress) recentDetectionsオブジェクトは更新されていますが、ページを再読み込みしない限り、ビューのテーブルは変更されません。

何が間違っているのかわからず、悩んでいます。 どなたか教えてください。

解決方法は?

あなたのサービスのコードが、何らかの理由でAngularのゾーンから外れている可能性があります。これは変更検知を壊してしまいます。これはうまくいくはずです。

import {Component, OnInit, NgZone} from 'angular2/core';

export class RecentDetectionComponent implements OnInit {

    recentDetections: Array<RecentDetection>;

    constructor(private zone:NgZone, // <== added
        private recentDetectionService: RecentDetectionService) {
        this.recentDetections = new Array<RecentDetection>();
    }

    getRecentDetections(): void {
        this.recentDetectionService.getJsonFromApi()
            .subscribe(recent => { 
                 this.zone.run(() => { // <== added
                     this.recentDetections = recent;
                     console.log(this.recentDetections[0].macAddress) 
                 });
        });
    }

    ngOnInit() {
        this.getRecentDetections();
        let timer = Observable.timer(2000, 5000);
        timer.subscribe(() => this.getRecentDetections());
    }
}

その他の変更検出の方法については、以下を参照してください。 Angularで変更検知を手動で起動する

変更検知を呼び出す別の方法として

ChangeDetectorRef.detectChanges()

現在のコンポーネントとその子コンポーネントの変更検出を即座に実行します。

ChangeDetectorRef.markForCheck()

Angularが次に変更検知を実行するときに現在のコンポーネントを含めるようにする。

ApplicationRef.tick()

アプリケーション全体の変更検出を実行するために