Angular 数组变化检测问题
Angular array change detection issue
我正在开发一个通知组件,其中有一个 "error" 对象数组,并使用 *ngFor
遍历它们。我的问题是 Angular 当我在订阅中改变它时,它不会获取对数组的更改。
我的代码如下:
ngOnInit() {
this.store.select().pipe(
map(state => state.error),
filter(error => !!error),
map(error => ({text: error, display: 'block'}))
).subscribe(error => {
// this does not get detected
this.errors.push(error);
setTimeout(() => {
error.display = 'none';
}, 4000)
});
// this gets detected
this.errors.push({
text: 'asd',
display: 'block'
})
}
以及相关的html:
<div class="notification-wrapper">
<div *ngFor="let error of errors" [style.display]="error.display" class="notification is-danger has-text-right">
{{ error.text }}
</div>
</div>
奇怪的是,如果我用不断添加虚拟错误的 setInterval
替换订阅,更改会被 Angular 捕捉到并且它表现正常。
有人可以向我解释为什么会这样吗,也许如何解决这个问题?谢谢。
看起来您的代码是在 Angular 区域之外执行的。
你可以在里面强制运行它:
import { NgZone } from '@angular/core';
constructor(private ngZone: NgZone) {}
...
this.store.select().pipe(
map(state => state.error),
filter(error => !!error),
map(error => ({text: error, display: 'block'}))
).subscribe(error => {
this.ngZone.run(() => {
this.errors.push(error);
setTimeout(() => {
error.display = 'none';
}, 4000)
});
});
我正在开发一个通知组件,其中有一个 "error" 对象数组,并使用 *ngFor
遍历它们。我的问题是 Angular 当我在订阅中改变它时,它不会获取对数组的更改。
我的代码如下:
ngOnInit() {
this.store.select().pipe(
map(state => state.error),
filter(error => !!error),
map(error => ({text: error, display: 'block'}))
).subscribe(error => {
// this does not get detected
this.errors.push(error);
setTimeout(() => {
error.display = 'none';
}, 4000)
});
// this gets detected
this.errors.push({
text: 'asd',
display: 'block'
})
}
以及相关的html:
<div class="notification-wrapper">
<div *ngFor="let error of errors" [style.display]="error.display" class="notification is-danger has-text-right">
{{ error.text }}
</div>
</div>
奇怪的是,如果我用不断添加虚拟错误的 setInterval
替换订阅,更改会被 Angular 捕捉到并且它表现正常。
有人可以向我解释为什么会这样吗,也许如何解决这个问题?谢谢。
看起来您的代码是在 Angular 区域之外执行的。 你可以在里面强制运行它:
import { NgZone } from '@angular/core';
constructor(private ngZone: NgZone) {}
...
this.store.select().pipe(
map(state => state.error),
filter(error => !!error),
map(error => ({text: error, display: 'block'}))
).subscribe(error => {
this.ngZone.run(() => {
this.errors.push(error);
setTimeout(() => {
error.display = 'none';
}, 4000)
});
});