以模板形式验证复选框列表(不是反应形式)Angular 2

时间:2017-08-15 20:21:17

标签: angular angular2-forms angular-validation

如何验证是否从Angular 2模板表单中的复选框列表中选中了至少1个复选框?

HTML代码。

   <div class="form-control" style="max-height: 300px; overflow: auto">
        <div *ngFor="let item of items" class="checkbox">
            <label for="{{item.id}}">
                <input type="checkbox" value="{{item.id}}" required id="{{item.id}}" [(ngModel)]="item.isSelected" />
                <span class="text-body">{{item.name}}</span>
            </label>
        </div>
   </div>
   <div *ngIf="!isAtleastOneItemSelected()" class="alert alert-error">
        Select at least one item
   </div>

组件代码。

public isAtleastOneItemSelected() {
    const selectedItems = this.items.filter((item) => item.isSelected);
    if (selectedItems.length > 0) {
        return true;
    } else {
        return false;
    }
}

我已经检查了Reactive表单执行此操作的方式here。因此,想要检查我们如何在模板表单中执行此操作。 使用我上面粘贴的代码,事情工作正常但在页面加载时出现错误消息,因为没有检查脏或触摸那里。我一直坚持这个问题。

对此有任何帮助将不胜感激。

感谢。

2 个答案:

答案 0 :(得分:0)

看看这个,你需要适应:

<div *ngFor="let item of items; let i = index" class="checkbox"> 
        <label for="{{item.id}}">
            <input type="checkbox" value="{{item.id}}" required id="{{item.id}}" [(ngModel)]="item.isSelected" (change)="CheckBoxChanged(i,$event)"/>
            <span class="text-body">{{item.name}}</span>
        </label>
 </div>
   <div [hidden]="isAtleastOneItemSelected()" class="alert alert-error">
        Select at least one item
   </div>

将检查逻辑放在这里......:

CheckBoxChanged(i,e){
    console.log(i);
    if (e.target.checked)
       console.log("checked");
    else 
       console.log("unchecked");
}

答案 1 :(得分:0)

我在这里看到两个可行的选择。我会选择第一个,因为我建议避免模板中的任何方法,因为你不能限制方法被触发的时间和频率。特别是如果您有一种以多种方式修改数据的视图,即使它与实际的复选框无关,也会触发该方法。稍后寻找样本。

所以我要做的就是改变

*ngIf="!isAtleastOneItemSelected()"

检查变量:

*ngIf="nonChecked"

并且在单击复选框时会发生某种类型的更改事件 某种方法,例如:

check() {
  const selectedItems = this.items.filter((item) => item.isSelected === true);
  if (selectedItems.length > 0) {
     this.nonChecked = false;
  } else {
     this.nonChecked = true;
  }    
}

现在只有在触摸复选框时才会触发。

我看到的另一个选项,如果你想保持类似的设置,就是将复选框包装在一个表单组中,并观察触摸组的时间,然后只有在没有检查项目的情况下显示错误消息。因此,您可以将复选框包装在一个组中:

<div ngModelGroup="checkboxes">
  <!-- .... -->
</div>

然后你可以这样做:

<div *ngIf="!isAtleastOneItemSelected() && f.controls?.checkboxes?.dirty">
  Select at least one item
</div>  

其中f是表单的名称。但正如前面提到的,这将触发更改检测并在DOM中执行任何其他操作。下面是这个解决方案的一个示例,我们在DOM中只有一个其他字段(参见控制台),所以如果你有很多东西在进行,我建议第一个解决方案:)但不管怎样,两者都是作品!

http://plnkr.co/edit/VuLNR8H3lasFoK7mRDlG?p=preview