Динамически устанавливать валидаторы SubForm из родительского компонента - PullRequest
0 голосов
/ 26 сентября 2019

Я создавал многоразовые подчиненные формы в Angular 8, и с помощью FormGroupDirective получить ссылку на родителя FormGroup для ребенка довольно легко сделать, но мне трудно разобраться, какдинамически устанавливать валидаторы на дочерней форме от родителя.

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

// PARENT COMPONENT
public ngAfterViewInit() {
  // Form controls have been applied to the form group
  console.log('ngAfterViewInit', this.form.value);

  // BUT the validators of profile form aren't being set?
  this.form.get('profile').get('description').setValidators([Validators.required]);
}

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

Возможно ли динамически устанавливать валидаторы подчиненной формы, не передавая их через @Input привязок?

1 Ответ

0 голосов
/ 26 сентября 2019

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

this.form.get('profile').get('description').updateValueAndValidity();

В итоге это выглядит так:

public ngAfterViewInit() {
  // Form controls will now exist
  console.log('ngAfterViewInit', this.form.value);

  // BUT the validators of the profile form should not allow submission if set to required, and they do?

  this.form.get('profile').get('description').setValidators([Validators.required]);
  this.form.get('profile').get('description').updateValueAndValidity();
}

Когда выСделав это, вы получите сообщение об ошибке в консоли:

ERROR
Error: ExpressionChangedAfterItHasBeenCheckedError: 
Expression has changed after it was checked. 
Previous value: 'ng-valid: true'. Current value: 'ng-valid: false'.

, которое можно преодолеть, используя ChangeDetectorRef и вызывая this.changeDetector.detectChanges(), или обновив стратегию обнаружения изменений родительского компонента, указав ChagneDetectionStrategy.OnPush.

constructor(private changeDetector: ChangeDetectorRef) { }

// Removed for brevity

public ngAfterViewInit() {
  const descControl = this.form.get('profile').get('description');
  descControl.setValidators([Validators.required]);
  descControl.updateValueAndValidity();

  this.changeDetector.detectChanges();
}
@Component({
  selector: 'app-page',
  templateUrl: './page.component.html',
  styleUrls: ['./page.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class PageComponent implements OnInit, AfterContentInit, AfterViewInit {
  // Removed for brevity

  public ngAfterViewInit() {
    const descControl = this.form.get('profile').get('description');
    descControl.setValidators([Validators.required]);
    descControl.updateValueAndValidity();
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...