I am new to angular and trying to combine with easyui angular.
I found this error when trying to open/close dialog:
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'klass: l-btn f-inline-row f-content-center l-btn-small l-btn-focus'. Current value: 'klass: l-btn f-inline-row f-content-center l-btn-small'.
And here is my code.
user.component.html
<eui-linkbutton (click)="addAction()" iconCls="icon-add" style="margin-bottom:10px">Add New</eui-linkbutton>
<eui-datagrid
[data]="users" style="height1:250px" [filterable]="true"
[selectionMode]="'single'"
[(selection)]="rowSelected"
[euiContextMenu]="contextMenu"
>
</eui-datagrid>
<!-- contextmenu -->
<eui-menu #contextMenu (itemClick)="contextClick($event)">
<eui-menu-item value="edit" text="Edit"></eui-menu-item>
<eui-menu-item text="Delete"></eui-menu-item>
<eui-menu-item text="View"></eui-menu-item>
</eui-menu>
<eui-dialog #formDialog [closed]="closed" [draggable]="true" [modal]="true" [title]="isNewRow ? 'Add' : 'Edit'" (close)="closed=true">
<div class="dialog-button">
<eui-linkbutton [disabled]="!formObj.valid" (click)="saveAction()" style="width:80px">Save</eui-linkbutton>
<eui-linkbutton (click)="formDialog.close()" style="width:80px">Cancel</eui-linkbutton>
</div>
</eui-dialog>
user.component.ts
export class UserComponent implements OnInit {
rowSelected = null;
formObj: FormGroup;
constructor(public userService: UserService, fb: FormBuilder){
}
get row(){
return this.rowSelected;
}
set row(value: any){
this.rowSelected = value;
this.formObj.reset(this.rowSelected);
}
editAction(row){
this.row = this.rowSelected;
this.closed = false;
}
addAction(){
console.log('open babe');
this.row = {
'id' : null,
'username' : null,
'password' : null,
'email' : null,
'first_name' : null,
'last_name' : null
};
this.closed = false;
}
isNewRow = false;
editingRow = null;
closed = true;
users: Object;
currentSelection = null;
ngOnInit() {
this.userService.getData().subscribe(
data => this.users = data
)
console.log('ngoninit');
this.initRow();
this.closed = true;
}
initRow() {
this.editingRow = {
username: null,
password: null,
email: null,
first_name: null,
last_name: null,
};
}
onAddRow() {
console.log('open babe');
this.initRow();
this.isNewRow = true;
this.closed = false;
}
onEditRow(row) {
this.isNewRow = false;
this.editingRow = row;
this.closed = false;
}
contextClick(value){
if(!this.rowSelected){
alert('Please select a row first!');
}
else{
if(value == 'edit'){
this.editAction(this.rowSelected);
}
}
}
}
I have search many tutorial to fix this problem but it seems like the tutorial condition doesn't match with mine.
Do i misunderstand something or missing something practical about angular? what is the proper way to update attribute?
Navigate up the call stack until you find a template expression where the value displayed in the error has changed. Ensure that there are no changes to the bindings in the template after change detection is run. This often means refactoring to use the correct component lifecycle hook for your use case.
A good way to fix the ExpressionChangedAfterItHasBeenCheckedError is to make Angular aware of the fact that you have changed the code after it has completed its first check. You can do this by using setTimeout to make the error go away.
ngAfterViewInit()linkA callback method that is invoked immediately after Angular has completed initialization of a component's view. It is invoked only once when the view is instantiated.
Use ChangeDetectorRef
Service to detect new changes
When a view uses the OnPush
(checkOnce) change detection strategy, explicitly marks the view as changed so that it can be checked again.
import { Component, Input, ChangeDetectionStrategy,ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'component',
templateUrl: 'component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
constructor(cdRef:ChangeDetectorRef){}
ngAfterViewInit() {
this.cdRef.detectChanges();
}
I was getting this error after modifying a Map
object that was being iterated over using
*ngFor="let entry of myMap.entries()"
The fix that worked for me was just to add ChangeDetectionStrategy.OnPush
to my component declaration:
@Component({
selector: 'component',
templateUrl: 'component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
Can't able to see the open/close dialog code. Here is explanation for the issue. Usually Angular Updates the DOM based on Model object with help of Change Detection. Angular updates the DOM and it got reflected in UI, After that Model also got updated.
Angular don't know what needs to do, so it's reporting an error. We need to manually trigger the change detection in order to reflect the DOM. Try to wrap the section of code inside setTimeout Block
setTimeout(()=>{
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With