angular - 为什么 Angular 组件在点击后才更新?
问题描述
我是 Angular 的新手,所以我不会对我缺少基本的东西感到惊讶。我尝试了 Angular 文档和谷歌搜索,但目前还不知道为什么我的组件在单击后才更新 UI?
我的场景是,我想要一个名为 NotificationComponent 的共享组件和一个名为NotificationService的共享服务。由于我可能会发生 1 个以上的错误,因此我的NotificationComponent应该显示所有这些消息。最重要的是,我有一个 http 错误拦截器和一个自定义错误处理。
发生的事情是,我收到 3 个 https 错误,拦截器收到所有 3 个错误,自定义错误处理正在处理所有 3 个错误,通知服务正在创建所有 3 个错误,但通知组件仅自动呈现 1 个(有时是 2 个)错误。一旦我单击 UI 中的任意位置,就会显示提醒消息。为什么会这样?
层次结构:AppModule
导入SharedModule
[包含通知服务和组件]。通知组件选择器在里面app.component.html
零件:
@Component({
selector: 'app-notification',
templateUrl: './notification.component.html',
styleUrls: ['./notification.component.scss']
})
export class NotificationComponent implements OnInit, OnDestroy {
messages: Message[] = [];
notificationSubscription: Subscription;
constructor(private notificationService: NotificationService) { }
ngOnInit() {
this.notificationSubscription = this.notificationService.onNotify()
.subscribe(msg => {
this.messages.push(msg);
});
}
ngOnDestroy() {
// unsubscribe to avoid memory leaks
this.notificationSubscription.unsubscribe();
}
}
HTML:
<div *ngFor = "let msg of messages" role="alert">
{{msg.detail}}
</div>
服务:
@Injectable({
providedIn: 'root'
})
export class NotificationService {
messages: Message[];
private subject = new Subject<Message>();
constructor() {
this.messages = [];
}
onNotify(): Observable<Message> {
return this.subject.asObservable();
}
error(title: string, detail: string): void {
this.notify({type: 'error', title: title, detail: detail});
}
notify(message: Message) {
this.subject.next(message);
}
}
自定义错误处理程序:
@Injectable()
export class CustomErrorHandler implements ErrorHandler {
constructor(@Inject(NotificationService)
private notificationService: NotificationService) {
}
handleError(error: any): void {
this.notificationService.error(error.title, error.detail);
}
}
PS:我不限于任何特定的实现,所以如果需要我可以改变方法。
解决方案
在您的课程中NotificationComponent
,注入并显式更新数组,以便 Angular 可以推断该属性已更改并因此更新 UIChangeDetectorRef
constructor
messages
constructor(
private readonly changeDetector: ChangeDetectorRef,
private readonly notificationService: NotificationService
) {}
public ngOnInit(): void {
this.notificationSubscription = this.notificationService
.onNotify()
.subscribe({
next: (msg) => {
// Don't mutate existing array, Angular can't infer if it should update UI
this.messages = [...this.messages, msg];
// explicitly update UI if the above approach doesn't work
this.changeDetector.detectChanges();
}
});
}
推荐阅读
- kotlin-native - Kotlin/Native share code project startup?
- google-app-engine - 新 gcloud 系统中的 GAE appcfg.py request_logs 相当于什么
- php - 如何将 Wordpress 帖子中的链接重定向到子目录?
- python - 将位哈希转换为十六进制,然后再转换回位哈希
- mongodb - 如何在 mongo 聚合中使用 map 内部查找来查找数组中的所有元素
- javascript - Summernote lite 项目符号和编号列表不默认为自定义默认字体大小
- python - 使用 urllib 请求更改或创建超时
- php - 子目录中的 PHP 脚本在调用时自动请求根目录中的相同脚本
- javascript - 如何处理使用 Vue.js 动态生成的多个表单
- javascript - 如何使用 php + html + ajax 删除一行?