각도 2 - 모델 변경 후 뷰가 업데이트되지 않음
몇 초마다 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)
최근 탐지 개체가 업데이트되고 있지만 페이지를 다시 로드하지 않는 한 보기의 테이블이 변경되지 않습니다.
제가 여기서 뭘 잘못하고 있는지 보려고 애쓰고 있습니다.누가 도와줄 수 있습니까?
당신의 서비스에 있는 코드가 어떻게든 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());
}
}
변경 감지를 호출하는 다른 방법은 각도에서 수동으로 변경 감지 트리거를 참조하십시오.
변경 감지를 호출하는 다른 방법은 다음과 같습니다.
ChangeDetectorRef.detectChanges()
현재 구성 요소 및 하위 구성 요소에 대해 변경 탐지를 즉시 실행합니다.
ChangeDetectorRef.markForCheck()
다음 번 각도 실행 시 현재 구성 요소를 포함하는 변경 감지
ApplicationRef.tick()
전체 응용 프로그램에 대해 변경 탐지 실행
원래는 @Mark Rajcok의 댓글에 있는 답변이지만 ChangeDetectorRef를 사용하여 테스트되고 솔루션으로 작동한 것으로 여기에 배치하고 싶습니다. 여기에 좋은 점이 있습니다.
다른 대안은 주사하는 것입니다.
ChangeDetectorRef
와 콜cdRef.detectChanges()
대신에zone.run()
이는 다음과 같은 전체 구성 요소 트리에 대해 변경 감지를 실행하지 않기 때문에 더 효율적일 수 있습니다.zone.run()
합니다. – 마크 라즈콕
코드는 다음과 같아야 합니다.
import {Component, OnInit, ChangeDetectorRef} from 'angular2/core';
export class RecentDetectionComponent implements OnInit {
recentDetections: Array<RecentDetection>;
constructor(private cdRef: ChangeDetectorRef, // <== added
private recentDetectionService: RecentDetectionService) {
this.recentDetections = new Array<RecentDetection>();
}
getRecentDetections(): void {
this.recentDetectionService.getJsonFromApi()
.subscribe(recent => {
this.recentDetections = recent;
console.log(this.recentDetections[0].macAddress);
this.cdRef.detectChanges(); // <== added
});
}
ngOnInit() {
this.getRecentDetections();
let timer = Observable.timer(2000, 5000);
timer.subscribe(() => this.getRecentDetections());
}
}
편집: 사용.detectChanges()
구독자 내부에서 문제가 발생할 수 있습니다. 삭제된 보기 사용 시도: 변경 사항 탐지
그것을 해결하기 위해 당신은 해야 합니다.unsubscribe
구성 요소를 파괴하기 전에 전체 코드는 다음과 같습니다.
import {Component, OnInit, ChangeDetectorRef, OnDestroy} from 'angular2/core';
export class RecentDetectionComponent implements OnInit, OnDestroy {
recentDetections: Array<RecentDetection>;
private timerObserver: Subscription;
constructor(private cdRef: ChangeDetectorRef, // <== added
private recentDetectionService: RecentDetectionService) {
this.recentDetections = new Array<RecentDetection>();
}
getRecentDetections(): void {
this.recentDetectionService.getJsonFromApi()
.subscribe(recent => {
this.recentDetections = recent;
console.log(this.recentDetections[0].macAddress);
this.cdRef.detectChanges(); // <== added
});
}
ngOnInit() {
this.getRecentDetections();
let timer = Observable.timer(2000, 5000);
this.timerObserver = timer.subscribe(() => this.getRecentDetections());
}
ngOnDestroy() {
this.timerObserver.unsubscribe();
}
}
저는 이것이 오래된 질문이라는 것을 알지만 저는 제 상황을 공유하고 싶었습니다.저는 팀에서 일하고 있고 누군가는 기본적으로 자동 변경 감지를 비활성화하는 Push에 변경 감지 전략을 설정했습니다.이게 다른 도움이 될지는 모르겠지만 만약을 대비해서요.
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
https://angular.io/api/core/ChangeDetectionStrategy
저 같은 경우에도 비슷한 문제가 있었습니다.상위 구성 요소에서 호출하는 함수 내부에서 보기를 업데이트하는 중이었고, 상위 구성 요소에서 @ViewChild(NameOfMyChildComponent)를 사용하는 것을 잊었습니다.나는 이 어리석은 실수 때문에 적어도 3시간을 잃었습니다. 즉, 나는 그 어떤 방법도 사용할 필요가 없었습니다.
- 디텍터를 변경합니다. 디텍터를 변경합니다()
- Detector Ref.
- ApplicationRef.tick()
영역 및 변경 감지를 처리하는 대신 AsyncPipe가 복잡성을 처리하도록 합니다.이렇게 하면 관찰 가능한 구독, 구독 취소(메모리 누수 방지) 및 Angular 숄더에서 변경 감지가 수행됩니다.
새 요청의 결과를 내보내는 관찰 가능한 클래스로 변경합니다.
export class RecentDetectionComponent implements OnInit {
recentDetections$: Observable<Array<RecentDetection>>;
constructor(private recentDetectionService: RecentDetectionService) {
}
ngOnInit() {
this.recentDetections$ = Observable.interval(5000)
.exhaustMap(() => this.recentDetectionService.getJsonFromApi())
.do(recent => console.log(recent[0].macAddress));
}
}
AsyncPipe를 사용하도록 보기를 업데이트합니다.
<tr *ngFor="let detected of recentDetections$ | async">
...
</tr>
덧붙이고 싶은 것은, 다음과 같은 방법으로 서비스를 만드는 것이 더 낫다는 것입니다.interval
다음과 같이 지정합니다.
- 요청 (「 」를 )
exhaustMap
위의 코드에서와 같이); - 요청 오류 처리
- 오프라인 상태일 때 브라우저가 새 요청을 하지 못하도록 합니다.
언급URL : https://stackoverflow.com/questions/36919399/angular-2-view-not-updating-after-model-changes
'programing' 카테고리의 다른 글
iOS 8 iPad에서 UIAactivityView 컨트롤러 충돌 (0) | 2023.05.21 |
---|---|
분기 기준 변경 (0) | 2023.05.21 |
기본 변경 기본 iOS 시뮬레이터 장치 대응 (0) | 2023.05.21 |
su를 사용하여 나머지 bash 스크립트를 해당 사용자로 실행하려면 어떻게 해야 합니까? (0) | 2023.05.21 |
급여표에서 세 번째 또는 네 번째 최대 급여를 찾는 방법은 무엇입니까? (0) | 2023.05.21 |