3

我正在使用带有表单构建器和表单数组的 angular6 反应形式。我在表单数组的下拉菜单中遇到重复主题条目的问题。如何验证以避免从数组中重复输入。

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

堆栈闪电战

ts代码

 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>

4

1 回答 1

1

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

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})
      }
    }
  })
})

查看堆栈闪电战

于 2019-07-28T09:15:46.087 回答