Angular - можно создать FormGroup из не предопределенного объекта? - PullRequest
0 голосов
/ 07 ноября 2019

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

Итак, обычно при создании FormGroups в angular вы обычно знаете, как пометить или назвать каждое поле или FormControl, потому что, как правило, вы знаете свойства, которые ваша форма должна контролировать и проверять заранее. Так, например, для ранее известного myHouse объекта я мог бы сделать:

myHouse = new FormGroup({
  door: [''],
  size: [''],
  windows: new FormGroup({
    size: [''],
    clarity: ['']
    ...
  });
})

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

  • Родительский компонент создает массив объектов, которые яназвали filterPreferences и передает его моему компоненту Filter, который получает его как @Input (). Объект будет выглядеть так:

    this.filterPreferences = [{
      filterName: 'status',
      filterKey: 'Estado',
      options: [
        {
          optionName: 'open',
          optionKey: 'Abierta'
        },
        {
          optionName: 'closed',
          optionKey: 'Cerrada'
        },
        {
          optionName: 'ended',
          optionKey: 'Finalizada'
        }
      ]
    

    ... и другие объекты после этого. }]

  • В этом массиве объектов filterName ссылается на тип параметра, тогда как optionName ссылается на различные опции, которые может иметь указанный параметр ( состояние элемента )может быть открыто , закрыто или закончено ). Свойства filterKey и optionKey, используемые для переводов i18l.

  • Дочерний компонент (компонент Filter) получит этот массив объектов и создаст на его основе FormGroup или FormArray, так что, когда пользовательЗакончив выбор серии фильтров, дочерний компонент может передать этот выбор своему родителю.

Суть в том, что мой компонент не может знать поля или параметры с самого начала,как и в примере с house FormGroup ранее. Различные родительские компоненты могут передавать различные информационные блоки этому компоненту. Каждый родительский компонент будет использовать одинаковую структуру filterNames, filterKeys, optionNames и т. Д., Но количество записей и имен каждого параметра будет отличаться для каждого.

Попытка проиллюстрировать мои (неудачные) попытки с помощьюсвоего рода псевдокод, я чувствую, что должен сделать что-то вроде:

- в моих объявлениях const formArray = this.formBuilder.array ([]);

createForm() {
  this.filterPreferences.forEach((item) => {
    const optionNames = item.options.map(( opt ) => opt.optionName);
    item.FilterName = new FormGroup({
      optionNames = new FormControl('');
    })
    this.formArray.push(item.filterName);
  )}
}

По сути, итерация по моему filterPreferences объекту или массиву объектов и создание formGroup для каждого объекта. HTML-код для этой формы будет выглядеть следующим образом:

      <div class="filters" [formGroup]="formGroup">
        <ng-container *ngFor="let filter of filterPreferences">
          <div class="filter-options">
            <h4>{{filter.filterKey}}</h4>
            <div *ngFor="let options of filter.options">
              <app-checkbox-input
              formControlName="{{options.optionName}}"
              class="float-left mr-3 mb-3"
              [label]=" options.optionKey ">
              </app-checkbox-input>
            </div>
          </div>
        </ng-container>
</div>

Кто-нибудь сталкивался с такой проблемой ранее, и если да, то как вы ее обошли?

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

Если мне удастся решить эту проблему, я опубликую свои выводы в качестве ответа.

1 Ответ

0 голосов
/ 08 ноября 2019

Хорошо, так что я решил большинство проблем.

Главная ошибка, с которой я столкнулся, заключается в том, что я не осознавал, что каждый мой блок 'options' фактически создается внутри собственного formGroup. Таким образом, ключевым элементом, который я пропустил, был:

      <div class="filters" [formGroup]="formGroup">
        <ng-container *ngFor="let filter of filterPreferences">
          <div class="filter-options">
       ---- a new div for the formGroups ------
            <div formGroupName="{{filter.filterName}}">

            <h4>{{filter.filterKey}}</h4>
            <div *ngFor="let options of filter.options">
              <app-checkbox-input
              formControlName="{{options.optionName}}"
              class="float-left mr-3 mb-3"
              [label]=" options.optionKey ">
              </app-checkbox-input>
            </div>
            </div>
       ----- end of the new div -----
          </div>
        </ng-container>
      </div>

Обратите внимание на ссылку для formGroupname внутри нового div.

С этим, например, в следующемblock:

  filterName: 'status',
  filterKey: 'Estado',
  options: [
    {
      optionName: 'open',
      optionKey: 'Abierta'
    },
    {
      optionName: 'closed',
      optionKey: 'Cerrada'
    },
    {
      optionName: 'ended',
      optionKey: 'Finalizada'
    }
  ]

My .ts создает эту группу форм:

status: this.formBuilder.group({
  open: [''],
  closed: [''],
  ended: ['']
})

Мой html может затем перебирать свой "let options of filter.options" и, поскольку ссылка на formGroupName находится за пределами этого ngForцикл, имя указанного formGroupName остается неизменным.

Ну, это более или менее. Если кто-то наткнется на эту ветку и захочет получить дополнительную информацию или советы о том, как это было сделано, не стесняйтесь спрашивать.

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