Im working on Angular 2.0 (Yes, a bit behind from current 2.4).
I have a checkbox list. Im trying to make that when the LAST CHECKBOX IS UNCHECKED all CHECKBOXES ARE CHECKED.
HTML
<div *ngFor="let filter of filters">
<label htmlFor="check-box-{{filter.text}}"
[ngClass]="(filter.selected)? 'active' : '' ">
<input type="checkbox"
name="check-box-{{filter.text}}"
[checked]="filter.selected"
(change)="onSelectFilter(filter)"
attr.id="check-box-{{filter.text}}">
{{filter.selected}} - ({{filter.counter}})
</label>
</div>
TS
onSelectFilter(filter: Filter){
filter.toggleSelection();
let isAnyFilterSelected = this.filters.find(filter => filter.selected);
// If no filter is selected then ALL filters are selected
if(!isAnyFilterSelected){
this.filters.forEach(filter => filter.selected = true );
}
}
I create a plunker for it.
https://plnkr.co/edit/uzF6Lk5fxRZjXBOaS9ob?p=preview
If unchecked the only checkbox with CHECKED attribute TRUE, Im expecting that ALL checkboxes would have CHECKED attribute. This does not happen.
Any ideas?
You should use
ngModel
instead of binding tochecked
, and use asetTimeout
.plunkr
"why such a fishy trick is needed ?"
Actually, because from change-detector's point of view, there is no change between the previous state and the new one.
So there is no need to update the
@Input()
of the child /call thewriteValue()
method of theControlValueAccessor
(<input type="checkbox" [ngModel]="foo">
).Using setTimeout, you first update the property to false, then delay its change back to initial state, allowing a new change-detection cycle.
Also note that events like
(ngModelChange)
are not correlated to the change-detection cycle.Without
setTimeout()
:Here, we will get the same result as in your example, while we keep
foo
being true, the checkbox won't update :The code (plunkr):
What is happening under the hood :
With
setTimeout()
This time we will delay resetting the value to a next tick using
setTimeout
:The code (plunkr):
What is happening under the hood :