Angular ReactiveForms: Створення масиву значень прапорців?


104

Враховуючи список прапорців, прив'язаних до того самого 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', ...]

ти знайшов якесь рішення?
КП

Це, мабуть, найбільш надмірно спроектований спосіб робити прапорці у формі коли-небудь. Це зовсім не просто.
mwilson

8
Кутовий. Все, що я намагаюся зробити, - це отримати килимок-радіогрупу для зв’язування у моїй реактивній формі. Я не пам’ятаю, щоб я так боровся з кутовим. Усі статті вказують на одне і те ж. Просто не можу змусити його працювати. Все інше надзвичайно просто. Напевно, я занадто довго на це дивлюся. Досі просто здається, що занадто багато складності для значення масиву у формі.
мвілсон,

3
Так , це було жахливо , коли я запитав це в 2016 році, і це все ще страшно в 2019 році
ReactingToAngularVues

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

Відповіді:


52

За допомогою тихої відповіді відповіді я написав рішення для отримання значень замість станів у моєму 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>

компонент.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, якщо ваша модель вже має перевірені значення.


як мені перевірити, чи встановлено прапорець, коли я завантажую дані після використання вашого прикладу для входу в db?
Девора

У цьому рішенні форма завжди дійсна, навіть якщо прапорець не встановлений
Тея

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

48

Ось гарне місце для використання FormArray https://angular.io/docs/ts/latest/api/forms/index/FormArray-class.html

Для початку ми створимо наш масив елементів управління за допомогою a FormBuilderабо нового aFormArray

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
для ідентифікатора міг бути використаний індекс *ngFor="let control of checkboxGroup.controls['myValues'].controls ; let i=index""
Мірза

9
Це круто, але створює повністю загальний масив прапорців. Імовірно, ви завантажували б масив або щось інше і пов'язували кожен прапорець з іншим значенням. Як додати, наприклад, текстовий рядок для використання в мітці форми до кожного елемента керування формою?
Askdesigners

НМ Я щойно наніс на карту поруч із зовнішнім масивом: p
Askdesigners

@Askdesigners чи можете ви опублікувати своє рішення, щоб мати прапорці та мітки?
eddygeek

25

Зробити це в Angular 6 значно легше, ніж у попередніх версіях, навіть коли інформація про прапорець заповнюється асинхронно з API.

Перше, що слід усвідомити, це те, що завдяки keyvalueтрубі Angular 6 нам більше не потрібно користуватися FormArray, і ми можемо вкласти a 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 (), і прапорці у вашій формі будуть динамічно відображати масив значень прапорців
Arjan

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 (value) .filter (([_, isSelected]) => isSelected) .map (([key]) => key); console.log (список); `
zauni

1
Найкраще рішення imho. Ви можете розмістити завдання const checkboxes = ..поза фоку;)
Бернуллі, IT,

Що трапляється, коли ключ елемента дорівнює тому ж, що й інше поле форми? Наприклад, у мене є два різні масиви прапорців, кожен з яких має клавіші "Маленький", "Середній" та "Великий"?
Ньюклік

9

Якщо ви шукаєте значення прапорців у форматі JSON

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

Повний приклад тут .

Перепрошую за те, що використовую назви країн як значення прапорця замість тих, що містяться у питанні. Подальше пояснення -

Створіть групу форм для форми

 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>

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

Але найчастіше ми хочемо отримати лише список ідентифікаторів категорії як ["category2", "category3"]. Я також повинен написати get, щоб взяти ці дані. Мені подобається такий підхід краще порівняно з 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;
  };
}

6

Я не бачу тут рішення, яке повністю відповідає на питання, використовуючи реактивні форми в повній мірі, тому ось моє рішення для того самого.


Підсумок

Ось суть детального пояснення разом із прикладом StackBlitz.

  1. Використовуйте FormArrayдля прапорців та ініціалізуйте форму.
  2. valueChangesСпостережуваним ідеально підходить , коли ви хочете форму для відображення чого - то , але магазин що - то ще в компоненті. Тут відобразіть true/ falseзначення до потрібних значень.
  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, ми можемо спостерігати зміни в , 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 також має код, коли ви хочете передати значення за замовчуванням прапорцям, щоб вони були позначені як позначені в інтерфейсі.


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>

компонент.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
    }
}

Це вловлює подію після того, як Angular Forms її вже змінили на true або false, якщо це правда, я змінюю ім'я на ім'я того, що представляє прапорець, яке при необхідності також оцінить як true, якщо воно перевіряється на true / false як Ну.


Це вивело мене на правильний шлях, в підсумку я зробив це this.customForm.patchValue ({[[event.target.id]: event.target. checked});
Demodave

4

Якщо ви хочете використовувати кутову реактивну форму ( 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


Легко найкраще рішення для мене. Дуже дякую.
Ньюклік

2

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

formArrayName = "сповіщення"

(change) = "updateChkbxArray (n.id, $ event. selected, 'сповіщення')"

Таким чином він може працювати для декількох прапорців масивів в одній формі. Просто встановіть ім'я масиву елементів керування, щоб підключатись кожного разу.

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>

компонент.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.