Реактивные формы - на valueChanges опции подписки / обновления - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь добиться чего-то вроде этого, у меня есть набор результатов с тремя опциями bmw, audi и opel, в выборке я могу выбрать только один из вариантов, но при необходимости пользователь все еще может выбрать не выбранный опции (чекбоксы) Набор результатов:

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

Поток:

Например, скажем, в выбранном мной выбранном BMW , поэтому после выбора мне нужно показать два флажка, потому что 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

В настоящий момент я не совсем понимаю, как получить индекс конкретной машины (выбранный в списке выбора) и обновить / убрать флажки.

Результат:

  1. Флажки показывают только те опции, которые не выбраны в select
  2. если я изменю выбранное значение на что-то другое, мне нужно обновить флажки, чтобы показать опции, оставшиеся от набора результатов.

Комментарии:

Может быть, мне даже не нужно использовать removeAt (FormArray), а просто простой _filter подчеркивания и отфильтровать на основе идентификатора? Но как я могу отфильтровать FormArray на основе определенного значения (: id)?

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

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

1 Ответ

0 голосов
/ 11 января 2019

попробовать:

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

...