nao*_*omi 24 angular2-changedetection angular
我有一个简单的场景,但只是无法让它工作!
在我看来,我在一个高度有限的盒子里显示一些文字.
正在从服务器获取文本,因此视图会在文本进入时更新.
现在我有一个"扩大"按钮,有一个ngIf是要显示的按钮,如果在框中的文本溢出.
问题在于,因为文本在获取时会发生变化,所以"扩展"按钮的条件会true在Angular的变化检测结束后变为...
所以我得到了这个错误:表达式在检查后发生了变化.上一个值:'false'.当前值:'true'.
显然按钮没有显示......
看到这个Plunker(检查控制台以查看错误...)
知道如何使这项工作?
Tie*_*han 40
发生此错误,因为您在dev mode:
在dev mode更改检测中,在每次常规更改检测运行后添加一个额外的转弯,以检查模型是否已更改.
所以,要强制更改检测运行下一个tick,我们可以这样做:
export class App implements AfterViewChecked {
show = false; // add one more property
constructor(private cdRef : ChangeDetectorRef) { // add ChangeDetectorRef
//...
}
//...
ngAfterViewChecked() {
let show = this.isShowExpand();
if (show != this.show) { // check if it change, tell CD update view
this.show = show;
this.cdRef.detectChanges();
}
}
isShowExpand()
{
//...
}
}
Run Code Online (Sandbox Code Playgroud)
现场演示:https://plnkr.co/edit/UDMNhnGt3Slg8g5yeSNO?p=preview
Par*_*sha 23
实施AfterContentChecked方法。
constructor(
private cdr: ChangeDetectorRef,
) {}
ngAfterContentChecked(): void {
this.cdr.detectChanges();
}
Run Code Online (Sandbox Code Playgroud)
cs_*_*pil 18
出于某种原因,@Tiep Phan 的回答对我强制更改检测不起作用,但使用 setTimeout(也强制更改检测)可以。
我也只需要将它添加到有问题的行中,它与我在 ngOnInit 中已有的代码一起工作得很好,而不必添加 ngAfterViewInit。
例子:
ngOnInit() {
setTimeout(() => this.loadingService.loading = true);
asyncFunctionCall().then(res => {
this.loadingService.loading = false;
})
}
Run Code Online (Sandbox Code Playgroud)
更多细节在这里:https : //github.com/angular/angular/issues/6005
Nik*_*ani 15
在 ngAfterContentChecked 为我解决问题后导致更改检测器运行
示例如下:
import { ChangeDetectorRef,AfterContentChecked} from '@angular/core'
export class example implements OnInit, AfterContentChecked {
ngAfterContentChecked() : void {
this.changeDetector.detectChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
虽然,当我阅读一些文章时,这个问题在生产模式下得到解决,无需任何必要的修复。
以下是此类问题的可能原因:
它强制执行单向数据流:当我们的控制器类上的数据更新时,更改检测会运行并更新视图。
但是视图的更新本身不会触发进一步的更改,而这些更改又会触发对视图的进一步更新
https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/
为了解决这个问题,您可以将更改 *ngIf 状态的变量从ngAfterViewInit移动到ngOnInit或构造函数。因为在调用 AfterViewInit 方法时不允许更改 html 的状态。
正如 @tiep-phan 所说,另一种方法是将 ChangeDetectorRef 传递给构造函数,并在 AfterViewInit 方法中更改 *ngIf 的状态后调用 this.chRef.detectChanges() 。
我们还可以通过将changeDetection更改为OnPush来抑制抛出此ExpressionChangedAfterItHasBeenCheckedError。因此,不会执行额外的更改检测,因此不会引发错误。为此,您需要在.ts文件中添加装饰器的一部分,如下所示:ChangeDetectionStrategy.OnPush@Component
@Component({
selector: 'your-component',
templateUrl: 'your-component.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
30713 次 |
| 最近记录: |