Angular ReactiveForms: создание массива значений флажков?


105

Учитывая список флажков, привязанных к одному и тому же formControlName, как я могу создать массив значений флажков, привязанных к formControl, а не просто true/ false?

Пример:

<form [formGroup]="checkboxGroup">
    <input type="checkbox" id="checkbox-1" value="value-1" formControlName="myValues" />
    <input type="checkbox" id="checkbox-2" value="value-2" formControlName="myValues" />
    <input type="checkbox" id="checkbox-3" value="value-2" formControlName="myValues" />
</form>

checkboxGroup.controls['myValues'].value в настоящее время производит:

true or false

Что я хочу, чтобы это произвело:

['value-1', 'value-2', ...]

ты нашел какое-нибудь решение?
CP

Это, вероятно, наиболее продуманный способ установки флажков в форме. Это совсем непросто.
mwilson

8
Угловой. Все, что я пытаюсь сделать, это заставить радиоактивную группу связать в моей реактивной форме. Я не помню, чтобы я так сильно боролся с angular. Все статьи указывают на одно и то же. Просто не могу заставить его работать. Все остальное очень просто. Я, наверное, слишком долго смотрел на это. По-прежнему кажется, что слишком много сложностей для значения массива в форме.
mwilson

3
Да , это было ужасно , когда я спросил это в 2016 году, и это все еще страшно в 2019 году
ReactingToAngularVues

3
Я не добавляю тонны к этому вопросу, но я хотел, чтобы другие знали, что я чувствую то же самое. Одно это было самой сложной частью в изучении угловых реактивных форм. Я чувствую, что это не должно быть так сложно. Однако я рад видеть, что я не одинок в борьбе. Так что спасибо за вопрос.
NorthStarCode

Ответы:


51

С помощью ответа сайленсода я написал решение для получения значений вместо состояний в моем formBuilder.

Я использую метод для добавления или удаления значений в formArray. Это может быть плохой подход, но он работает!

component.html

<div *ngFor="let choice of checks; let i=index" class="col-md-2">
  <label>
    <input type="checkbox" [value]="choice.value" (change)="onCheckChange($event)">
    {{choice.description}}
  </label>
</div>

component.ts

// For example, an array of choices
public checks: Array<ChoiceClass> = [
  {description: 'descr1', value: 'value1'},
  {description: "descr2", value: 'value2'},
  {description: "descr3", value: 'value3'}
];

initModelForm(): FormGroup{
  return this._fb.group({
    otherControls: [''],
    // The formArray, empty 
    myChoices: new FormArray([]),
  }
}

onCheckChange(event) {
  const formArray: FormArray = this.myForm.get('myChoices') as FormArray;

  /* Selected */
  if(event.target.checked){
    // Add a new control in the arrayForm
    formArray.push(new FormControl(event.target.value));
  }
  /* unselected */
  else{
    // find the unselected element
    let i: number = 0;

    formArray.controls.forEach((ctrl: FormControl) => {
      if(ctrl.value == event.target.value) {
        // Remove the unselected element from the arrayForm
        formArray.removeAt(i);
        return;
      }

      i++;
    });
  }
}

Когда я отправляю свою форму, например, моя модель выглядит так:

  otherControls : "foo",
  myChoices : ['value1', 'value2']

Не хватает только одного: функции для заполнения formArray, если ваша модель уже проверила значения.


как мне проверить, установлен ли мой флажок, когда я загружаю данные после использования вашего примера для входа в базу данных?
Devora

В этом решении форма всегда действительна, даже если флажок не установлен
Teja

myChoices: new FormArray([], Validators.required)
Бикрам Нат,

"Но это работает!" так начинается технический долг. Это не способ сделать это в реактивной форме. Одним из преимуществ использования элементов управления формы для каждого ввода флажка является то, что они могут запоминать свое состояние, даже когда вы повторно добавляете их в DOM.
MIWMIB

50

Вот хорошее место для использования FormArray https://angular.io/docs/ts/latest/api/forms/index/FormArray-class.html

Для начала мы создадим наш массив элементов управления либо с помощью, либо с FormBuilderпомощьюFormArray

FormBuilder

this.checkboxGroup = _fb.group({
  myValues: _fb.array([true, false, true])
});

новый FormArray

let checkboxArray = new FormArray([
  new FormControl(true),
  new FormControl(false),
  new FormControl(true)]);

this.checkboxGroup = _fb.group({
  myValues: checkboxArray
});

Достаточно просто сделать, но затем мы собираемся изменить наш шаблон и позволить шаблонному движку обрабатывать то, как мы привязываемся к нашим элементам управления:

template.html

<form [formGroup]="checkboxGroup">
    <input *ngFor="let control of checkboxGroup.controls['myValues'].controls"
    type="checkbox" id="checkbox-1" value="value-1" [formControl]="control" />     
  </form>

Здесь мы повторяем наш набор FormControlsв нашем myValues FormArrayи для каждого элемента управления, который мы привязываем [formControl]к этому элементу управления, а не к элементу FormArrayуправления, и <div>{{checkboxGroup.controls['myValues'].value}}</div>производимtrue,false,true а также делаем синтаксис вашего шаблона немного менее ручным.

Вы можете использовать этот пример: http://plnkr.co/edit/a9OdMAq2YIwQFo7gixbj?p=preview, чтобы ковыряться


1
возможно, вам следует удалить id = "xxx", идентификатор должен быть уникальным, верно?
PeiSong Xiong

1
для id может быть использован индекс *ngFor="let control of checkboxGroup.controls['myValues'].controls ; let i=index""
Мирза

9
Это круто, но дает совершенно общий набор флажков. Предположительно, вы загружаете массив или что-то еще и связываете каждый флажок с каким-то другим значением. Как добавить, например, текстовую строку для использования в метке формы к каждому элементу управления формы?
Askdesigners

Н.М. Я только что сопоставил это с внешним массивом: p
Askdesigners

@Askdesigners, можете ли вы опубликовать свое решение с флажками и ярлыками?
eddygeek

26

В Angular 6 это сделать значительно проще, чем в предыдущих версиях, даже когда информация о флажке заполняется асинхронно из API.

Первое, что нужно понять, это то, что благодаря каналу Angular 6 keyvalueнам больше не нужно использовать FormArray, и вместо этого мы можем вложитьFormGroup .

Сначала передайте FormBuilder в конструктор

constructor(
    private _formBuilder: FormBuilder,
) { }

Затем инициализируйте нашу форму.

ngOnInit() {

    this.form = this._formBuilder.group({
        'checkboxes': this._formBuilder.group({}),
    });

}

Когда данные наших флажков доступны, повторите их, и мы можем вставить их прямо во вложенные FormGroupкак именованные FormControl, без необходимости полагаться на массивы поиска с индексированными числами.

const checkboxes = <FormGroup>this.form.get('checkboxes');
options.forEach((option: any) => {
    checkboxes.addControl(option.title, new FormControl(true));
});

Наконец, в шаблоне нам просто нужно перебрать keyvalueфлажки: никаких дополнительных let index = i, и флажки автоматически будут в алфавитном порядке: намного чище.

<form [formGroup]="form">

    <h3>Options</h3>

    <div formGroupName="checkboxes">

        <ul>
            <li *ngFor="let item of form.get('checkboxes').value | keyvalue">
                <label>
                    <input type="checkbox" [formControlName]="item.key" [value]="item.value" /> {{ item.key }}
                </label>
            </li>
        </ul>

    </div>

</form>

1
Также очень удобно использовать в случае простого жестко запрограммированного массива значений флажков. Затем вы можете добавить элементы управления формы, используя аналогичный цикл for прямо сейчас в ngOnInit (), и флажки в вашей форме будут динамически отражать массив значений
Арджан

3
Это все еще выдержки [key1 = true, key2 = false, key3 = true]. Мы хотим ['key1', 'key3']
f.khantsis

@ f.khantsis Это можно сделать так: `const value = {key1: true, key2: false, key3: true}; const list = Object.entries (значение) .filter (([_, isSelected]) => isSelected) .map (([key]) => key); console.log (список); `
zauni

2
Лучшее решение имхо. Вы можете разместить назначение const checkboxes = ..вне foreach;)
Bernoulli IT

Что происходит, когда ключ элемента совпадает с другим полем формы? Например, у меня есть два разных массива флажков, каждый с клавишами «Маленький», «Средний» и «Большой»?
Newclique

9

Если вы ищете значения флажков в формате JSON

{ "name": "", "countries": [ { "US": true }, { "Germany": true }, { "France": true } ] }

Полный пример здесь .

Прошу прощения за использование названий стран в качестве значений флажков вместо указанных в вопросе. Дальнейшее объяснение -

Создайте FormGroup для формы

 createForm() {

    //Form Group for a Hero Form
    this.heroForm = this.fb.group({
      name: '',
      countries: this.fb.array([])
    });

    let countries=['US','Germany','France'];

    this.setCountries(countries);}
 }

Пусть каждый флажок будет FormGroup, созданной из объекта, единственным свойством которого является значение флажка.

 setCountries(countries:string[]) {

    //One Form Group for one country
    const countriesFGs = countries.map(country =>{
            let obj={};obj[country]=true;
            return this.fb.group(obj)
    });

    const countryFormArray = this.fb.array(countriesFGs);
    this.heroForm.setControl('countries', countryFormArray);
  }

Массив FormGroups для флажков используется для установки элемента управления для «стран» в родительской форме.

  get countries(): FormArray {
      return this.heroForm.get('countries') as FormArray;
  };

В шаблоне используйте канал, чтобы получить имя для элемента управления флажком

  <div formArrayName="countries" class="well well-lg">
      <div *ngFor="let country of countries.controls; let i=index" [formGroupName]="i" >
          <div *ngFor="let key of country.controls | mapToKeys" >
              <input type="checkbox" formControlName="{{key.key}}">{{key.key}}
          </div>
      </div>
  </div>

7

Я не вижу здесь решения, которое полностью отвечает на вопрос с использованием реактивных форм в максимальной степени, поэтому вот мое решение для того же самого.


Резюме

Вот суть подробного объяснения вместе с примером StackBlitz.

  1. Используйте FormArrayдля флажков и инициализируйте форму.
  2. valueChangesНаблюдаемым идеально подходит , когда вы хотите форму для отображения чего - то , но магазин что - то еще в компоненте. Сопоставьте true/false values ​​с желаемыми значениями.
  3. Отфильтровать false значения во время отправки.
  4. Отписаться от valueChangesнаблюдаемых.

Пример StackBlitz


Детальное объяснение

Используйте FormArray для определения формы

Как уже упоминалось в ответе отмечен как правильный. FormArrayэто способ пойти в таких случаях, когда вы предпочитаете получать данные в виде массива. Итак, первое, что вам нужно сделать, это создать форму.

checkboxGroup: FormGroup;
checkboxes = [{
    name: 'Value 1',
    value: 'value-1'
}, {
    name: 'Value 2',
    value: 'value-2'
}];

this.checkboxGroup = this.fb.group({
    checkboxes: this.fb.array(this.checkboxes.map(x => false))
});

Это просто установит начальное значение всех флажков на false .

Затем нам нужно зарегистрировать эти переменные формы в шаблоне и выполнить итерацию по checkboxesмассиву (НЕ FormArrayпо данным флажка), чтобы отобразить их в шаблоне.

<form [formGroup]="checkboxGroup">
    <ng-container *ngFor="let checkbox of checkboxes; let i = index" formArrayName="checkboxes">
        <input type="checkbox" [formControlName]="i" />{{checkbox.name}}
    </ng-container>
</form>

Используйте наблюдаемое valueChanges

Вот часть, о которой я не упоминаю ни в одном из приведенных здесь ответов. В таких ситуациях, как эта, когда мы хотели бы отобразить указанные данные, но сохранить их как что-то еще, valueChangesнаблюдаемое очень полезно. Используя valueChanges, мы можем наблюдать изменения в , checkboxesа затем mapв true/ falseзначения , полученные от FormArrayдо требуемых данных. Обратите внимание, что это не изменит выбор флажков, так как любое правдивое значение, переданное флажку , помечает его как отмеченное и наоборот.

subscription: Subscription;

const checkboxControl = (this.checkboxGroup.controls.checkboxes as FormArray);
this.subscription = checkboxControl.valueChanges.subscribe(checkbox => {
    checkboxControl.setValue(
        checkboxControl.value.map((value, i) => value ? this.checkboxes[i].value : false),
        { emitEvent: false }
    );
});

Это в основном сопоставляет FormArrayзначения с исходным checkboxesмассивом и возвращает, valueесли флажок отмечен как true, иначе он возвращается false. Здесь emitEvent: falseважен, так как установка FormArrayзначения без него приведет valueChangesк срабатыванию события, создающего бесконечный цикл. Установив emitEventна false, мы удостоверяясьvalueChanges наблюдаемое не излучает , когда мы устанавливаем значение здесь.

Отфильтруйте ложные значения

Мы не можем напрямую фильтровать falseзначения в, FormArrayпотому что это испортит шаблон, так как они привязаны к флажкам. Итак, лучшее возможное решение - отфильтровать falseзначения во время отправки. Для этого используйте оператор распространения.

submit() {
    const checkboxControl = (this.checkboxGroup.controls.checkboxes as FormArray);
    const formValue = {
        ...this.checkboxGroup.value,
        checkboxes: checkboxControl.value.filter(value => !!value)
    }
    // Submit formValue here instead of this.checkboxGroup.value as it contains the filtered data
}

Это в основном отфильтровывает ложные значения из файлаcheckboxes .

Отказаться от подписки на valueChanges

Наконец, не забудьте отказаться от подписки на valueChanges

ngOnDestroy() {
    this.subscription.unsubscribe();
}

Примечание. Существует особый случай, когда значение не может быть установлено на FormArrayвход valueChanges, т.е. если значение флажка установлено на число 0. Это будет выглядеть так, как будто флажок не может быть установлен, так как при установке флажка в FormControlкачестве числа 0(ложное значение) будет установлено, и, следовательно, он не будет установлен. Было бы предпочтительно не использовать число 0в качестве значения, но если это необходимо, вы должны условно установить 0какое-то истинное значение, скажем, строку '0'или просто, trueа затем при отправке преобразовать его обратно в число 0.

Пример StackBlitz

В StackBlitz также есть код, когда вы хотите передать флажкам значения по умолчанию, чтобы они помечались как отмеченные в пользовательском интерфейсе.


Это по-прежнему требует поддержки двух массивов и их синхронизации. Все еще не так чисто, как я надеялся. Возможно, мы сможем заставить элементы управления формы хранить комплексные значения вместо двух массивов.
MIWMIB

1
Сложное значение не сработало, потому что значение для флажка должно быть истинным или ложным. Так что это решение по-прежнему выглядит лучше всего.
MIWMIB

6

TL; DR

  1. Я предпочитаю использовать FormGroup для заполнения списка флажков
  2. Напишите собственный валидатор для проверки хотя бы одного флажка
  3. Рабочий пример https://stackblitz.com/edit/angular-validate-at-least-one-checkbox-was-selected

Иногда это также поражало меня, поэтому я попробовал оба подхода - FormArray и FormGroup.

В большинстве случаев список флажков был заполнен на сервере, и я получал его через API. Но иногда у вас будет статический набор флажков с вашим предопределенным значением. В каждом варианте использования будет использоваться соответствующий FormArray или FormGroup.

В основном FormArrayэто вариант FormGroup. Ключевое отличие состоит в том, что его данные сериализуются как массив (в отличие от сериализации как объекта в случае FormGroup). Это может быть особенно полезно, когда вы не знаете, сколько элементов управления будет присутствовать в группе, например, динамических форм.

Для простоты представьте, что у вас есть простая форма создания продукта с

  • Одно обязательное текстовое поле с названием продукта.
  • Список категорий для выбора, требующий проверки хотя бы одной. Предположим, список будет получен с сервера.

Во-первых, я создал форму только с названием продукта formControl. Это обязательное поле.

this.form = this.formBuilder.group({
    name: ["", Validators.required]
});

Поскольку категория динамически отображается, мне придется добавить эти данные в форму позже, когда данные будут готовы.

this.getCategories().subscribe(categories => {
    this.form.addControl("categoriesFormArr", this.buildCategoryFormArr(categories));
    this.form.addControl("categoriesFormGroup", this.buildCategoryFormGroup(categories));
})

Есть два подхода к созданию списка категорий.

1. Сформировать массив

  buildCategoryFormArr(categories: ProductCategory[], selectedCategoryIds: string[] = []): FormArray {
    const controlArr = categories.map(category => {
      let isSelected = selectedCategoryIds.some(id => id === category.id);
      return this.formBuilder.control(isSelected);
    })
    return this.formBuilder.array(controlArr, atLeastOneCheckboxCheckedValidator())
  }
<div *ngFor="let control of categoriesFormArr?.controls; let i = index" class="checkbox">
  <label><input type="checkbox" [formControl]="control" />
    {{ categories[i]?.title }}
  </label>
</div>

это buildCategoryFormGroup вернет мне FormArray. Он также принимает список выбранных значений в качестве аргумента, поэтому, если вы хотите повторно использовать форму для редактирования данных, это может быть полезно. Для создания новой формы продукта он пока не применим.

Заметил, что при попытке доступа к значениям formArray. Это будет похоже [false, true, true]. Чтобы получить список выбранных идентификаторов, потребовалось немного больше работы для проверки из списка, но на основе индекса массива. Мне это не нравится, но работает.

get categoriesFormArraySelectedIds(): string[] {
  return this.categories
  .filter((cat, catIdx) => this.categoriesFormArr.controls.some((control, controlIdx) => catIdx === controlIdx && control.value))
  .map(cat => cat.id);
}

Вот почему я пришел к использованию FormGroupв этом отношении

2. Группа форм

Отличие formGroup в том, что данные формы будут храниться в виде объекта, для чего требуется ключ и элемент управления формой. Поэтому рекомендуется установить ключ как categoryId, а затем мы сможем получить его позже.

buildCategoryFormGroup(categories: ProductCategory[], selectedCategoryIds: string[] = []): FormGroup {
  let group = this.formBuilder.group({}, {
    validators: atLeastOneCheckboxCheckedValidator()
  });
  categories.forEach(category => {
    let isSelected = selectedCategoryIds.some(id => id === category.id);
    group.addControl(category.id, this.formBuilder.control(isSelected));
  })
  return group;
}
<div *ngFor="let item of categories; let i = index" class="checkbox">
  <label><input type="checkbox" [formControl]="categoriesFormGroup?.controls[item.id]" /> {{ categories[i]?.title }}
  </label>
</div>

Значение группы форм будет выглядеть так:

{
    "category1": false,
    "category2": true,
    "category3": true,
}

Но чаще всего мы хотим получить только список categoryIds как ["category2", "category3"]. Я также должен написать прием, чтобы взять эти данные. Мне этот подход больше нравится по сравнению с formArray, потому что я действительно мог взять значение из самой формы.

  get categoriesFormGroupSelectedIds(): string[] {
    let ids: string[] = [];
    for (var key in this.categoriesFormGroup.controls) {
      if (this.categoriesFormGroup.controls[key].value) {
        ids.push(key);
      }
      else {
        ids = ids.filter(id => id !== key);
      }
    }
    return ids;
  }

3. Пользовательский валидатор для проверки хотя бы одного флажка был выбран.

Я сделал валидатор, чтобы проверить, по крайней мере, флажок X был выбран, по умолчанию он будет проверять только один флажок.

export function atLeastOneCheckboxCheckedValidator(minRequired = 1): ValidatorFn {
  return function validate(formGroup: FormGroup) {
    let checked = 0;

    Object.keys(formGroup.controls).forEach(key => {
      const control = formGroup.controls[key];

      if (control.value === true) {
        checked++;
      }
    });

    if (checked < minRequired) {
      return {
        requireCheckboxToBeChecked: true,
      };
    }

    return null;
  };
}

4

Сделайте событие, когда он щелкнет, а затем вручную измените значение true на имя того, что представляет флажок, тогда имя или true будет оценивать то же самое, и вы можете получить все значения вместо списка true / false. Пример:

component.html

<form [formGroup]="customForm" (ngSubmit)="onSubmit()">
    <div class="form-group" *ngFor="let parameter of parameters"> <!--I iterate here to list all my checkboxes -->
        <label class="control-label" for="{{parameter.Title}}"> {{parameter.Title}} </label>
            <div class="checkbox">
              <input
                  type="checkbox"
                  id="{{parameter.Title}}"
                  formControlName="{{parameter.Title}}"
                  (change)="onCheckboxChange($event)"
                  > <!-- ^^THIS^^ is the important part -->
             </div>
      </div>
 </form>

component.ts

onCheckboxChange(event) {
    //We want to get back what the name of the checkbox represents, so I'm intercepting the event and
    //manually changing the value from true to the name of what is being checked.

    //check if the value is true first, if it is then change it to the name of the value
    //this way when it's set to false it will skip over this and make it false, thus unchecking
    //the box
    if(this.customForm.get(event.target.id).value) {
        this.customForm.patchValue({[event.target.id] : event.target.id}); //make sure to have the square brackets
    }
}

Это перехватывает событие после того, как оно уже было изменено на true или false с помощью Angular Forms, если оно истинно, я меняю имя на имя того, что представляет собой флажок, который при необходимости также будет оцениваться как true, если он проверяется на true / false как хорошо.


Это привело меня к правильному пути, в итоге я сделал это this.customForm.patchValue ({[event.target.id]: event.target.checked});
Demodave

4

Если вы хотите использовать реактивную форму Angular ( https://angular.io/guide/reactive-forms ).

Вы можете использовать один элемент управления формы для управления выводимым значением группы флажков.

составная часть

import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { flow } from 'lodash';
import { flatMap, filter } from 'lodash/fp';

@Component({
  selector: 'multi-checkbox',
  templateUrl: './multi-checkbox.layout.html',
})
export class MultiChecboxComponent  {

  checklistState = [ 
      {
        label: 'Frodo Baggins',
        value: 'frodo_baggins',
        checked: false
      },
      {
        label: 'Samwise Gamgee',
        value: 'samwise_gamgee',
        checked: true,
      },
      {
        label: 'Merry Brandybuck',
        value: 'merry_brandybuck',
        checked: false
      }
    ];

  form = new FormGroup({
    checklist : new FormControl(this.flattenValues(this.checklistState)),
  });


  checklist = this.form.get('checklist');

  onChecklistChange(checked, checkbox) {
    checkbox.checked = checked;
    this.checklist.setValue(this.flattenValues(this.checklistState));
  }

  flattenValues(checkboxes) {
    const flattenedValues = flow([
      filter(checkbox => checkbox.checked),
      flatMap(checkbox => checkbox.value )
    ])(checkboxes)
    return flattenedValues.join(',');
  }
}

html

<form [formGroup]="form">
    <label *ngFor="let checkbox of checklistState" class="checkbox-control">
    <input type="checkbox" (change)="onChecklistChange($event.target.checked, checkbox)" [checked]="checkbox.checked" [value]="checkbox.value" /> {{ checkbox.label }}
  </label>
</form>

checklistState

Управляет моделью / состоянием входных данных контрольного списка. Эта модель позволяет сопоставить текущее состояние с любым нужным форматом значений.

Модель:

{
   label: 'Value 1',
   value: 'value_1',
   checked: false
},
{
  label: 'Samwise Gamgee',
  value: 'samwise_gamgee',
  checked: true,
},
{
  label: 'Merry Brandybuck',
  value: 'merry_brandybuck',
  checked: false
}

checklist Контроль формы

Этот элемент управления хранит значение, которое вы хотите сохранить, например,

вывод значения: "value_1,value_2"

См. Демонстрацию на https://stackblitz.com/edit/angular-multi-checklist


Для меня это просто лучшее решение. Огромное спасибо.
Newclique

2

Мое решение - решено для Angular 5 с представлением материалов
. Подключение осуществляется через

formArrayName = "уведомление"

(изменение) = "updateChkbxArray (n.id, $ event.checked, 'уведомление')"

Таким образом, он может работать с несколькими массивами флажков в одной форме. Просто задайте имя массива элементов управления для подключения каждый раз.

constructor(
  private fb: FormBuilder,
  private http: Http,
  private codeTableService: CodeTablesService) {

  this.codeTableService.getnotifications().subscribe(response => {
      this.notifications = response;
    })
    ...
}


createForm() {
  this.form = this.fb.group({
    notification: this.fb.array([])...
  });
}

ngOnInit() {
  this.createForm();
}

updateChkbxArray(id, isChecked, key) {
  const chkArray = < FormArray > this.form.get(key);
  if (isChecked) {
    chkArray.push(new FormControl(id));
  } else {
    let idx = chkArray.controls.findIndex(x => x.value == id);
    chkArray.removeAt(idx);
  }
}
<div class="col-md-12">
  <section class="checkbox-section text-center" *ngIf="notifications  && notifications.length > 0">
    <label class="example-margin">Notifications to send:</label>
    <p *ngFor="let n of notifications; let i = index" formArrayName="notification">
      <mat-checkbox class="checkbox-margin" (change)="updateChkbxArray(n.id, $event.checked, 'notification')" value="n.id">{{n.description}}</mat-checkbox>
    </p>
  </section>
</div>

В конце вы получаете возможность сохранить форму с массивом идентификаторов исходных записей для сохранения / обновления. Вид пользовательского интерфейса

Соответствующая часть json формы

Будем рады любым замечаниям по улучшению.


0

ЧАСТЬ ШАБЛОНА: -

    <div class="form-group">
         <label for="options">Options:</label>
         <div *ngFor="let option of options">
            <label>
                <input type="checkbox"
                   name="options"
                   value="{{option.value}}"
                   [(ngModel)]="option.checked"
                                />
                  {{option.name}}
                  </label>
              </div>
              <br/>
         <button (click)="getselectedOptions()"  >Get Selected Items</button>
     </div>

ЧАСТЬ КОНТРОЛЛЕРА: -

        export class Angular2NgFor {

          constructor() {
             this.options = [
              {name:'OptionA', value:'first_opt', checked:true},
              {name:'OptionB', value:'second_opt', checked:false},
              {name:'OptionC', value:'third_opt', checked:true}
             ];


             this.getselectedOptions = function() {
               alert(this.options
                  .filter(opt => opt.checked)
                  .map(opt => opt.value));
                }
             }

        }

1
Привет, @EchoLogic .. Пожалуйста, дайте мне знать, если у вас возникнут какие-либо вопросы
Абхишек Шривастава

1
Здесь используются не ReactiveForms, а обычные формы, поэтому не отвечает на вопрос
Гийом

0

Добавьте мои 5 центов) Модель моего вопроса

{
   name: "what_is_it",
   options:[
     {
      label: 'Option name',
      value: '1'
     },
     {
      label: 'Option name 2',
      value: '2'
     }
   ]
}

template.html

<div class="question"  formGroupName="{{ question.name }}">
<div *ngFor="let opt of question.options; index as i" class="question__answer" >
  <input 
    type="checkbox" id="{{question.name}}_{{i}}"
    [name]="question.name" class="hidden question__input" 
    [value]="opt.value" 
    [formControlName]="opt.label"
   >
  <label for="{{question.name}}_{{i}}" class="question__label question__label_checkbox">
      {{opt.label}}
  </label>
</div>

component.ts

 onSubmit() {
    let formModel = {};
    for (let key in this.form.value) {
      if (typeof this.form.value[key] !== 'object') { 
        formModel[key] = this.form.value[key]
      } else { //if formgroup item
        formModel[key] = '';
        for (let k in this.form.value[key]) {
          if (this.form.value[key][k])
            formModel[key] = formModel[key] + k + ';'; //create string with ';' separators like 'a;b;c'
        }
      }
    }
     console.log(formModel)
   }

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.