Angular 2-复选框未保持同步 [英] Angular 2 - Checkbox not kept in sync

查看:91
本文介绍了Angular 2-复选框未保持同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Angular 2.0(是的,比当前的2.4落后了一点).

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

如果取消选中唯一具有CHECKED属性为TRUE的复选框,则我希望所有复选框都具有CHECKED属性.这不会发生.

If unchecked the only checkbox with CHECKED attribute TRUE, Im expecting that ALL checkboxes would have CHECKED attribute. This does not happen.

有什么想法吗?

推荐答案

您应该使用ngModel而不是绑定到checked,并使用setTimeout.

You should use ngModel instead of binding to checked, and use a 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);
      });
    }
}

plunkr

实际上,因为从变更检测器的角度来看,以前的状态与新的状态之间没有变化.

Actually, because from change-detector's point of view, there is no change between the previous state and the new one.

因此无需更新子级的@Input()/调用).

So there is no need to update the @Input() of the child /call the writeValue() method of the ControlValueAccessor (<input type="checkbox" [ngModel]="foo">).

使用setTimeout,首先将属性更新为false,然后将其更改延迟回到初始状态,从而允许进行新的更改检测周期.

Using setTimeout, you first update the property to false, then delay its change back to initial state, allowing a new change-detection cycle.

还要注意,像(ngModelChange)这样的事件与变更检测周期无关.

Also note that events like (ngModelChange) are not correlated to the change-detection cycle.

在这里,我们将得到与您的示例相同的结果,尽管我们将foo设置为true,但复选框不会更新:

Here, we will get the same result as in your example, while we keep foo being true, the checkbox won't update :

@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将值重置为下一个刻度:

This time we will delay resetting the value to a next tick using setTimeout :

@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-复选框未保持同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆