我正在研究 Angular 2.0(是的,比当前的 2.4 有点落后)。
我有一个复选框列表。 我试图在最后一个复选框未选中时使所有复选框都被选中。
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 );
}
}
我为它创建了一个 plunker。
https://plnkr.co/edit/uzF6Lk5fxRZjXBOaS9ob?p=preview
如果取消选中唯一具有 CHECKED 属性 TRUE 的复选框,我希望所有复选框都具有 CHECKED 属性。这不会发生。
有什么想法吗?
最佳答案
你应该使用 ngModel
而不是绑定(bind)到 checked
,并使用 setTimeout
.
<div *ngFor="let filter of filters">
<label htmlFor="check-box-{{filter.text}}"
[ngClass]="(filter.selected)? 'active' : '' ">
<input type="checkbox"
name="check-box-{{filter.text}}"
[ngModel]="filter.selected"
(ngModelChange)="onSelectFilter($event,filter)"
attr.id="check-box-{{filter.text}}">
{{filter.selected}} - ({{filter.counter}})
</label>
</div>
onSelectFilter(selected:boolean,filter: Filter){
filter.selected=selected;
if(this.filters.every(filter=>!filter.selected)){
setTimeout(()=>{
this.filters.forEach(filter=>filter.selected=true);
});
}
}
“为什么需要这样的诡计?”
实际上,因为从变化检测器的 Angular 来看,之前的状态和新的状态之间没有变化。
因此无需更新 @Input()
child 的/调用writeValue()
ControlValueAccessor
的方法(<input type="checkbox" [ngModel]="foo">
)。
使用 setTimeout,您首先将属性更新为 false,然后将其更改延迟回初始状态,允许新的更改检测周期。
另请注意,类似 (ngModelChange)
的事件与变化检测周期无关。
没有setTimeout()
:
在这里,我们将得到与您的示例相同的结果,同时我们保留 foo
为真,复选框不会更新:
代码(plunkr):
@Component({
selector: 'my-app',
template: `
<input id="foo" type="checkbox" [ngModel]="foo" (ngModelChange)="fooChange($event)"><label for="foo">{{foo}}</label>
`,
})
export class App {
filters:[];
foo=true
fooChange(newValue:boolean){
if(newValue===false)
this.foo=true; // if newValue is false, foo becomes true
else
this.foo = newValue; // otherwise, do change
}
}
引擎盖下发生了什么:
与setTimeout()
这次我们将使用 setTimeout
延迟将值重置为下一个报价单:
代码(plunkr):
@Component({
selector: 'my-app',
template: `
<input id="foo" type="checkbox" [ngModel]="foo" (ngModelChange)="fooChange($event)"><label for="foo">{{foo}}</label>
`,
})
export class App {
filters:[];
foo=true
fooChange(newValue:boolean){
this.foo=newValue; // we need to make it change !
setTimeout(()=>{
if(newValue===false)
this.foo=true; // if newValue is false, foo becomes true
else
this.foo = newValue; // otherwise, do change
})
}
}
引擎盖下发生了什么:
关于Angular 2 - 复选框不同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43339450/