反应形式 - 在 valueChanges 订阅/更新复选框选项

Reactive forms - On valueChanges subscribe / update checkbox options

我想要实现的是这样的,我有一个包含三个选项的结果集 bmw,audi 和 opel,在 select 我只能 select 其中一个选项,但如果需要,用户仍然可以 select 而不是 selected 选项(复选框) 结果集:

cars = [
    { id: 1, name: 'bmw' },
    { id: 2, name: 'audi' },
    { id: 3, name: 'opel' }
];

流量:

例如,假设在 select 中我有 selected bmw,所以在 select 之后我需要显示两个复选框,因为 audi & opel 仍然是可用的选项。如果我将 bmw 更改为其他内容,我还需要更新复选框以显示那些未在 select.

中编辑的值

形式:

this.firstStepForm = this.fb.group({
  cars: [''], // select
  models: this.fb.array([]) // checkboxes
});

设置复选框:

private setupControls(details: any): void {
let control = <FormArray>this.firstStepForm.controls.models;

details.forEach(x => {
  control.push(this.fb.group({
    id: x.id,
    name: x.name
  }))
})

订阅更改:

this.firstStepForm.get('cars').valueChanges.subscribe((carId: number)

一个简单的例子 - stackblitz

目前,我不太明白如何获取特定汽车的索引(select在 select 中编辑)和 update/remove 复选框。

结果:

  1. 复选框仅显示未在 select
  2. 中 select 编辑的选项
  3. 如果我将 selected 值更改为其他值,我需要更新复选框以显示结果集中剩余的选项。

评论:

也许我什至不需要使用removeAt(FormArray),而只是一个简单的underscoreJs _filter & 根据id过滤掉?但是如何根据特定值(:id)过滤掉FormArray?

let magic = _.filter(arr, function (num) { return num != carId });

console.log('magic: ', magic);

尝试:

export class AppComponent implements OnInit {
  cars = [
    { id: 1, name: 'bmw' },
    { id: 2, name: 'audi' },
    { id: 3, name: 'opel' }
  ];
  firstStepForm: FormGroup;
  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.buildFirstStepForm();
    this.firstStepForm.get('cars').setValue(this.cars[0].id);
    this.onChange(this.cars[0].id); // initial first item select
  }

  onChange(e){
    let arr = this.cars.filter(item => item.id != e);
    this.models.controls = [];
    this.setupControls(arr)
  }

  get models(): FormArray {
    return <FormArray>this.firstStepForm.controls.models;
  }

  private buildFirstStepForm(): void {
    this.firstStepForm = this.fb.group({
      cars: [''],
      models: this.fb.array([])
    });
  }

  private setupControls(details: any): void {
    details.forEach(x => {
      this.models.push(this.fb.group({
        id: [x.id],
        name: [x.name]
      }))
    })
  }
}

html:

<form [formGroup]="firstStepForm" (ngSubmit)="submit()">
    <p>Select:</p>
    <select formControlName="cars" (change)="onChange($event.target.value)">
        <option *ngFor="let car of cars; let i = index" [value]="car.id">
            {{car.name}}
        </option>
    </select>
  <br>
  <br>
  <br>
  <p>Checkboxes:</p>
  <div class="form-check" *ngFor="let type of models.controls; let i = index">
    <label formArrayName="models">
      <input type="checkbox">{{type.value.name}}
    </label>
  </div>
</form>

DEMO