Как динамически добавлять элементы управления formgroup в formarray в angular, пока состояние управляется ngrx-формами? - PullRequest
1 голос
/ 19 апреля 2020

Я использую библиотеку ngrx-форм для управления состояниями моей формы.

Это библиотека: https://ngrx-forms.readthedocs.io/

Хорошо работает с простыми вводами для меня. Но когда дело доходит до динамических c элементов управления, я не уверен, как их использовать.

Например, допустим, у нас есть форма:

myform = this.fb.group({
topic: '',
books: [''],
languages: [''],
})

теперь элементы управления языками выглядят как this:

{language: '', code: ''}

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

но когда дело доходит до управления состоянием с использованием ngrx в сочетании с ngrx-формами, как я могу создать функцию редуктора для динамического добавления элементов управления языками?

1 Ответ

1 голос
/ 21 апреля 2020

Автор ngrx-форм здесь.

Возьмите следующий компонент, который создает форму, как вы описали выше, с @angular/forms.

export class ExampleComponent {
  private formBuilder = new FormBuilder();
  private form = this.formBuilder.group({});

  buildForm() {
    this.form = this.formBuilder.group({
      topic: '',
      languages: this.formBuilder.array([]),
    });

    this.addLanguageControlGroup();
  }

  addLanguageControlGroup(lang?: string, code?: string) {
    const newControl = this.formBuilder.group({
      language: lang || '',
      code: code || '',
    });

    (this.form.get('languages') as FormArray).push(newControl);
  }
}

С ngrx-forms код будет выглядеть так: (используя ngrx v8 +):

interface MyFormValue {
  topic: string;
  languages: LanguageFormValue[];
}

interface LanguageFormValue {
  language: string;
  code: string;
}

const INITIAL_FORM_VALUE: MyFormValue = {
  topic: '',
  languages: [
    {
      language: '',
      code: '',
    },
  ],
};

const myFormReducer = createReducer(
  {
    formState: createFormGroupState('MY_FORM', INITIAL_FORM_VALUE),
  },
  onNgrxForms(),
);

В вашем компоненте вы можете получить что-то вроде этого:

export class NgrxFormsExampleComponent {
  @Input() formState: FormGroupState<MyFormValue>;

  constructor(private actionsSubject: ActionsSubject) { }

  addLanguageControlGroup(lang?: string, code?: string) {
    this.actionsSubject.next(
      new AddArrayControlAction<LanguageFormValue>(
        this.formState.controls.languages.id,
        {
          language: lang || '',
          code: code || '',
        },
      )
    );
  }
}

Вместо использования встроенных AddArrayControlAction из ngrx-форм вы также можете создать свое собственное действие и затем добавить элемент управления в редуктор, например:

const addLanguageControlGroup = createAction(
  'MY_FORM/addLanguageControlGroup',
  (lang?: string, code?: string) => ({ lang, code }),
);

const myFormReducer = createReducer(
  {
    formState: createFormGroupState('MY_FORM', INITIAL_FORM_VALUE),
  },
  onNgrxForms(),
  on(addLanguageControlGroup, ({ formState }, { lang, code }) => ({
    formState: updateGroup(formState, {
      languages: addArrayControl({
        language: lang || '',
        code: code || '',
      }),
    }),
  })),
);

export class NgrxFormsExampleComponent {
  @Input() formState: FormGroupState<MyFormValue>;

  constructor(private actionsSubject: ActionsSubject) { }

  addLanguageControlGroup(lang?: string, code?: string) {
    this.actionsSubject.next(addLanguageControlGroup(lang, code));
  }
}

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...