Angular中subscribe内更新变量后视图未更新问题求助
问题
我希望基于API返回的数据更新commentInfo变量,在subscribe函数中已经获取到数据,但更新commentInfo后视图无法正常显示。代码如下:
import { Component, Input, NgZone } from '@angular/core'; import { CommentService } from './comment.service'; interface CommentInfo { by: string; id: number; parent: number; text: string; time: number; type: string; } @Component({ selector: 'app-comment', templateUrl: '<div class="comment-wrapper"> <div class="comment-desc"> {{commentInfo?.text}} </div> <div class="comment-time"> <div class="comment-desc"> {{commentInfo.time}} </div> </div> </div>', styleUrls: ['./comment.component.scss'], }) export class CommentComponent { @Input() commentId = 0; loadingComment = false; commentInfo : CommentInfo | undefined; constructor( private storyCommentService: CommentService, ) { } ngOnInit() { this.loadingComment = true; this.storyCommentService.getComment(this.commentId).subscribe((data) => { console.log(data) // data存在但无法更新下方的commentInfo this.commentInfo= data as CommentInfo; }) this.loadingComment = false; } }
解决方案
1. 修复异步加载状态的逻辑错误
当前this.loadingComment = false;是在subscribe外部同步执行的,API请求还没返回数据,加载状态就被改成false了。必须把这行代码移到subscribe的回调函数里,等数据拿到后再更新状态:
ngOnInit() { this.loadingComment = true; this.storyCommentService.getComment(this.commentId).subscribe((data) => { console.log(data); this.commentInfo = data as CommentInfo; this.loadingComment = false; // 数据返回后再关闭加载状态 }); }
2. 确保变更检测能捕获到变量更新
如果API请求的回调是在Angular变更检测范围外执行的,就需要手动触发检测,或者用NgZone把更新逻辑包裹起来:
首先在构造函数注入NgZone:
constructor( private storyCommentService: CommentService, private ngZone: NgZone ) { }
然后在subscribe回调里用ngZone.run包裹变量更新:
this.storyCommentService.getComment(this.commentId).subscribe((data) => { this.ngZone.run(() => { console.log(data); this.commentInfo = data as CommentInfo; this.loadingComment = false; }); });
3. 修复模板中的空值报错
模板里{{commentInfo.time}}没有用可选链操作符,当commentInfo还没初始化时会抛出错误,导致视图渲染失败。改成{{commentInfo?.time}}即可:
<div class="comment-time"> <div class="comment-desc"> {{commentInfo?.time}} </div> </div>
内容的提问来源于stack exchange,提问作者sye
相关产品推荐
相关产品推荐

