Многократно используемые вложенные подкомпоненты в формах (встроенные компоненты) с проверкой - PullRequest
0 голосов
/ 01 мая 2018

Допустим, у нас есть адрес, и мы хотим повторно использовать его в нескольких формах (например, Person, Company, ...) В Angular все являются компонентами, поэтому мы, вероятно, должны написать компонент.

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

1. Пользовательский компонент формы

Что мне не нравится в этом: чрезмерно сложный , все делегировано внутри подкомпонента. При валидации вам понадобится какая-то «внутренняя форма», чтобы валидация работала. Элементы управления формой должны быть определены в родительском элементе, инкапсуляция в действительности невозможна. Простой пример: https://stackblitz.com/edit/angular-nested-form-custum-component-test

2. Компонент, который имеет два входа: FormGroup и form-submit-state

Идея взята из https://medium.com/spektrakel-blog/angular2-building-nested-reactive-forms-7978ecd145e4

Гораздо проще, чем пользовательский компонент формы. Нам нужно предоставить FormGroup, которая построена вне вложенного компонента. Если мы хотим показать ошибки проверки «onSubmit», нам также необходимо предоставить «отправленное состояние» формы дочернему компоненту. Простой пример, см. https://stackblitz.com/edit/angular-nested-formcomponent-test

Любые комментарии или лучшие идеи для решения проблемы?

1 Ответ

0 голосов
/ 01 мая 2018

Демо

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

app.component.html

<nested-form-cmp 
     init="foo" 
     [formSubmitted]="f.submitted" 
     [grp]="myForm">
</nested-form-cmp>

AppComponent потребуется только для инициализации собственных данных формы:

export class AppComponent  {

  myForm: FormGroup;

  constructor(private fb: FormBuilder) {
      this.myForm = fb.group({
        name: ['', Validators.required]
      })
  }

  submit(form: NgForm) {
    console.log("Reactive Form submitted: " + form.submitted);
  }
}

вложенным-form.component.html

Вложенный компонент будет отвечать за создание собственной вложенной FormGroup и инициализацию ее с помощью валидаторов:

<div [formGroup]="grp">
  <div formGroupName="innerGrp">
  <label>
    Inner name:
    <input formControlName="name2" type="text" id="outer"/>   
  </label>
  <span class="error" *ngIf="(formSubmitted || grp.get('innerGrp.name2').touched) && grp.get('innerGrp.name2').hasError('required')">
    Inner name is required
  </span>
  </div>
</div>

вложенный-form.component.ts

export class NestedFormComponent implements OnInit{

  // The FormGroup built in the parent
  @Input() public grp: FormGroup;
  @Input() public init: string;

  // Needed, because the FormGroup does not get the forms submitted state
  @Input() public formSubmitted: boolean;
  constructor(private fb: FormBuilder){ 

  }

  ngOnInit() {
    this.grp.setControl('innerGrp', this.fb.group({
      name2: [this.init, Validators.required]
    }))
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...