Угловой - пользовательский компонент формы не отражает значение, непосредственное значение родительской группы - PullRequest
0 голосов
/ 19 сентября 2019

Возникла проблема с распространением значения из пользовательского компонента формы.

Если написать что-либо в Jobtitle, это будет отражено непосредственно от текущей к верхней группе форм.Та же самая вещь не работает в пользовательском компоненте, который является автоматическим добавлением-вводом.При написании в feeMode, затем отражать только в том же formControl.

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

Создан stackblitzкак показано ниже

https://stackblitz.com/edit/angular-auto-add-input?file=src/app/app.component.html

Пожалуйста, помогите мне, что я здесь пропустил.

группа реактивных форм

professional = this.fb.group({
    application: this.fb.group({
      jobTitle: ['', [Validators.required]],
      feeModel: this.fb.array([this.fb.control('', [Validators.required])], [Validators.required]),
      companyName: ['', [Validators.required]],
    })
  });

пользовательский компонент:

 @Component({
  selector: 'shared-auto-add-input',
  templateUrl: './auto-add-input.component.html',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => AutoAddInputComponent),
      multi: true
    }
  ]
})
export class AutoAddInputComponent implements OnInit, AfterViewInit {

  @Input() label: string;
  @Input() placeholder: string;
  @Input() max: number;
  @Input() formArrayName: string;
  @Input() errors: ErrorModel[];

  arrayControl: FormArray;
  form: FormGroup;

  constructor(
    @Optional() @Host() @SkipSelf()
    private controlContainer: ControlContainer,
    private fb: FormBuilder,
  ) { }

  ngOnInit() {
    if (!this.formArrayName) {
      throw new TypeError('\'formArrayName\' is required.');
    }
    this.form = this.fb.group({
      option: this.controlContainer.control.get(this.formArrayName)
    });
    this.arrayControl = this.form.get('option') as FormArray;
  }

  ngAfterViewInit() {
  }

  addOption() {
    this.arrayControl.push(this.fb.control('', this.controlContainer.control.get(this.formArrayName).validator));
  }

  removeOption(index: number) {
    this.arrayControl.removeAt(index);
  }

  stopNew(option, i) {
    return option.value === ''
      || i !== this.arrayControl.controls.length - 1
      || (this.max && this.arrayControl.controls.length === +this.max);
  }

  getErrors(error: FormControl) {
    let result = [];
    if (this.errors) {
      result = this.errors.filter((message) => {
        return error.hasError(message.key);
      });
    }
    return result;
  }
}

Ответы [ 3 ]

1 голос
/ 19 сентября 2019

Значение изменено, но нет события, инициируемого для повторной визуализации значений абсолютного родительского объекта.В дочернем компоненте вы работаете с new form только с ссылкой на исходный formControl или formarray.

this.fb({}) создает новую форму.Значения элемента управления изменяются, так как ссылка такая же, но затем не удается отобразить новое значение, так как не существует триггера от родительской формы, которую отслеживала родительская страница.

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

https://stackblitz.com/edit/angular-xchddm

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

Извините, я пропустил вызов updateValueAndValidity() после изменения значения в компоненте пользовательской формы

this.form.valueChanges
      .subscribe(() => {
        this.controlContainer.control.updateValueAndValidity();
      });

Теперь все работает.

Решено : https://stackblitz.com/edit/solved-angular-auto-add-input?file=src/app/auto-input/auto-add-input.component.ts

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

Похоже, вы боретесь с привязками данных в вашем HTML-файле, так как вы связываете полный объект для печати в HTML с помощью фильтра json.Кажется, он не учитывает изменения при перерисовке html, поскольку он должен сравнивать массив внутри объекта.Я не думаю, что это проблема (в зависимости от того, что вы хотите сделать).

Оказывается, angular выполняет проверку изменений и в зависимости от того, как вы связываете HTML, в вашем случае полный объект,он не проверяет, глубоко ли он изменился.

...