我目前正在实施需要条款和条件协议的角度项目。因此,我创建了一个300 px的可滚动div,其中从数据库中加载了内容。我们要强制用户在激活复选框之前阅读所有条款和条件。
在T&C繁重的情况下,它运行良好。当T&C点亮时,不会调用可滚动功能。因此,我想在加载结束时初始化复选框的禁用状态,但是会抛出ExpressionChangedAfterItHasBeenCheckedError
。
这是我的项目引起的轰动:https://stackblitz.com/edit/angular-b9p6rx
我尝试了许多解决方案:
*ngIf
替换为[hidden]
afterViewContentInit
div
内容上使用二传手我想避免setTimeout
调用来评估状态。
您看到什么解决方案?
有没有更好的方法来实现此功能?
先谢谢了。
app.component.html
<div class="content-box" *ngIf="isNotUpToDateCGU">
<h1>Terms and conditions</h1>
<span>
<i>{{agreementHeader1}}</i>
</span>
<br>
<div #cguContainer id="content" class="cgu-content" (scroll)="checkReading()" [innerHTML]="cguContent"></div>
<div class="text-right">
<span>I accept the terms and conditions</span>
<p-checkbox [(ngModel)]="areCGUAccepted" binary="true" [disabled]="!hasContentBeenRead"></p-checkbox>
</div>
<div class="text-right cgu-buttons">
<button type="button" class="btn btn-primary mx-2" >Annuler</button>
<button type="submit" class="btn btn-primary mx-2" [disabled]="!areCGUAccepted">Valider</button>
</div>
</div>
app.component.ts
export class AppComponent {
public agreementHeader1: string;
public cguContent: string;
public hasContentBeenRead: boolean = false;
public areCGUAccepted: boolean = false;
public isNotUpToDateCGU: boolean = false;
private cguContainerRef: ElementRef;
@ViewChild('cguContainer') set controlElRef(elementRef: ElementRef) {
if (elementRef) {
this.cguContainerRef = elementRef;
this.checkReading();
}
}
constructor(
private confService: ConfigurationService,
) { }
public ngOnInit(): void {
this.confService.getConfiguration('./terms.json')
.subscribe(result => {
this.agreementHeader1 = 'You have to read all terms and conditions to accept them';
// !!!!!!! invert the two lines to test with big terms
// this.cguContent = result.bigTerms;
this.cguContent = result.littleTerms;
this.isNotUpToDateCGU = true; // load template
});
}
public checkReading(): void {
let element = this.cguContainerRef.nativeElement;
// height of the div in css => height: 300px
if (element.scrollHeight - element.scrollTop < 301) {
this.hasContentBeenRead = true;
}
}
}
答案 0 :(得分:0)
仅当应用程序处于开发模式时才会发生这种情况。对于您而言,发生这种情况是因为在您设置this.isNotUpToDateCGU = true;
之后,不会发生新一轮的更改检测,直到将来可能会触发它。因此,在设置了this.isNotUpToDateCGU = true;
import { ChangeDetectorRef } from '@angular/core';
然后按如下所示使用它
constructor(
private confService: ConfigurationService,
private changeDetectorRef: ChangeDetectorRef
) { }
public ngOnInit(): void {
this.confService.getConfiguration('./terms.json')
.subscribe(result => {
this.agreementHeader1 = 'You have to read all terms and conditions to accept them';
// !!!!!!! invert the two lines to test with big terms
// this.cguContent = result.bigTerms;
this.cguContent = result.littleTerms;
this.isNotUpToDateCGU = true; // load template
this.changeDetectorRef.detectChanges();
});
}
希望这对您有帮助!