I know this issue with is still open, but according to this workaround Angular 2 - Checkbox not kept in sync it should work as expected, however I still struggle to make it work with my case.
I have the list of permissions which are granted to a role. When the user wants to update a role, I display the form with editable role name and the list of it's permissions as checkbox list. Now, I need to make some of the list items checked, if the role already has a permission from the list.
My form:
<tr *ngFor ="let perm of permissions, let i = index">
<td>
<label>
<input type="checkbox"
name="check-box-{{perm.permission_alias}}"
value="{{perm.permission_id}}"
(ngModel)="perm.checked"
(ngModelChange)="onSelectFilter($event,perm)"
attr.id="check-box-{{perm.permission_alias}}"
/>
{{perm.permission_alias}}
</label>
</td>
</tr>
My component:
getPermissions(role: Role): void {
this.permissions = [];
this.userService.getPermissions().then(perms => {
if (role != null) {
this.permissions = perms;
for (let rp of role.permissions) {
let index = this.permissions.indexOf(this.permissions.find(p => p.permission_id == rp.permission_id));
if (index >= 0) {
this.permissions[index].checked = true;
//this.onSelectFilter(true, this.permissions[index]); not sure if this should be called
}
}
console.log("before selected perms on update");
console.log(this.permissions);
}
else {
this.permissions = perms;
}
}).catch(this.handleError);
}
onSelectFilter(selected: boolean, filter: Permission) {
filter.checked = selected;
if (this.permissions.every(filter => !filter.checked)) {
setTimeout(() => {
this.permissions.forEach(filter => filter.checked = true);
});
}
}
I have no idea why this isn't working, I have no items checked in the list. I'd appreciate any help.
This works. It will always keep things in sync using 2-way data binding.
<input type="checkbox"
name="check-box-{{filter.text}}"
[(ngModel)]="filter.selected"
attr.id="check-box-{{filter.text}}">
If you need to trigger some function on change, use the change event.
<input type="checkbox"
name="check-box-{{filter.text}}"
[(ngModel)]="filter.selected"'
(change)="myCustomFun()"
attr.id="check-box-{{filter.text}}">
Updated the same in your plunk from your workaround link
I think that the error here is because you are always 'mutating the array'. When angular does the change detection run, it sees no changes, and the ngFor is not updated. Try this code, look that the only thing I am doing is making a copy of the array before I mutate it.
getPermissions(role: Role): void {
this.permissions = [];
this.userService.getPermissions().then(perms => {
if (role != null) {
this.permissions = perms;
for (let rp of role.permissions) {
let index = this.permissions.indexOf(this.permissions.find(p => p.permission_id == rp.permission_id));
if (index >= 0) {
this.permissions = this.permissions.slice(0) // copy the array.
this.permissions[index].checked = true;
//this.onSelectFilter(true, this.permissions[index]); not sure if this should be called
}
}
console.log("before selected perms on update");
console.log(this.permissions);
}
else {
this.permissions = perms;
}
}).catch(this.handleError);
}
onSelectFilter(selected: boolean, filter: Permission) {
filter.checked = selected;
if (this.permissions.every(filter => !filter.checked)) {
setTimeout(() => {
this.permissions = this.permissions.slice(0) // copy the array.
this.permissions.forEach(filter => filter.checked = true);
});
}
}
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