javascript - 如何验证 Angular 形式构建器数组中的重复条目?

标签 javascript html angular angular-reactive-forms angular-formbuilder

我正在使用带有表单生成器和表单数组的 angular6 react 表单。我在表单数组中的下拉列表中遇到重复主题条目的问题。如何验证以避免从数组中重复输入。

我有一个带有下拉列表的主题列表。当我单击添加按钮时,将添加一个主题数组。如果我添加类似的主题,它也会被添加。但我想避免重复主题条目。当我输入重复的主题时,将显示验证消息并且保存按钮将禁用。

stackblitz

代码

 olevelSubForm = this.fb.group({
   olevelSubArray: this.fb.array([
    ])
  });

 olevelSubjectList: any = [ 'Geography','Mathematics', 
 'Physics','Chemistry'];

 constructor(private fb: FormBuilder) {}

 ngOnInit() {
   this.addItemOlevel();
 }

 // olevel
 createOlevelSub(): FormGroup {
    return this.fb.group( {
        olevelSubject: new FormControl('', Validators.compose(
            [
                Validators.required
            ]
        )),
    });
  }

 addItemOlevel() {
    const control = <FormArray>this.olevelSubForm.controls.olevelSubArray;
    control.push(this.createOlevelSub());
 }

 saveData() {
  console.log('saved')
 }

html代码

 <form [formGroup]="olevelSubForm" >
  <div formArrayName="olevelSubArray">
   <table>
    <thead>
      <tr style="font-size: 15px;">
       <th>Subject</th>
      </tr>
    </thead>
      <tbody>

       <tr *ngFor="let item of olevelSubForm.get('olevelSubArray').controls; let i = index;" [formGroupName]="i">
         <td>
          <select formControlName="olevelSubject">
            <option *ngFor="let olevelSub of olevelSubjectList" [value]="olevelSub">{{ olevelSub }}</option>
          </select>
         </td>
         <td>
            <button style="float: right" [disabled]="olevelSubForm.invalid"(click)="addItemOlevel()"> Add
          </button>
         </td>
       </tr>

    </tbody>
  </table>
   <button [disabled]="olevelSubForm.invalid"(click)=saveData()>Save</button>
    <pre> {{ olevelSubForm.value | json }} </pre>
  </div>

最佳答案

在我的评论中,我提出并回答了不同的问题:您可以选择的选项在每个级别都不同,因此您不能选择一些尚未选择的选项。那,如果你有这样的功能

getSubjectForFormArray(i, olevelSubjectList) {
    return i == 0 ? olevelSubjectList :
      this.getSubjectForFormArray(i - 1, olevelSubjectList.filter(x => 
           x != this.olevelSubForm.get('olevelSubArray').value[i-1].olevelSubject))
  }

Yes 是一个递归函数,从所有选项开始,在每一步中,从列表中删除我们选择的值。所以,你的选项列表可以是这样的

<option *ngFor="let olevelSub of getSubjectForFormArray(i, olevelSubjectList)"
   [value]="olevelSub">{{ olevelSub }}</option>

无论如何,这不会避免,例如,如果我们选择“数学”、“化学”,如果将第一个组合更改为化学,我们将得到两个“化学”。因此,我们将检查数组的每个更改。那是在 ngOnInit

this.olevelSubForm.get('olevelSubArray').valueChanges.subscribe(res=>{
  res.forEach((x,index)=>{
    //res is the value of the array,e.g. -in one moment- 
    //[{olevelSubject:'Mathematics'},{olevelSubject:'Chemistry'},{olevelSubject:null}]
    if (index)
    {
      //before becomes an array with the values selected before, eg.  -in one moment-
      //   ['Mathematics','Chemistry']
      const before=res.slice(0,index).map(x=>x.olevelSubject)
      if (before.find(x=>x==res[index].olevelSubject))
      {    
          (this.olevelSubForm.get('olevelSubArray') as FormArray)
            .at(index).setValue({olevelSubject:null})
      }
    }
  })
})

参见 stackblitz

关于javascript - 如何验证 Angular 形式构建器数组中的重复条目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57230889/

相关文章:

javascript - '{ }' 在 javascript 中的含义

javascript - Handsontable 中 'Date' 列的排序问题

html - 左边div的文字根据右边div的内容居中

javascript - jQuery - not 运算符无法按预期工作

angular - net::ERR_CONNECTION_REFUSED 与 angular2 中的 http post

javascript - jQuery 选择不具有包含特定单词的类的 div

javascript - 在javascript中获取总秒数

python - 如何在 html 表中编辑从数据库中获取的数据? flask ,Jinja2

asp.net core - 将异常描述传递给客户端(例如 Angular)

arrays - 在 Angular 中过滤表单数组