Как получить значение для Control внутри FormArray в Angular при отображении записи для операции patchValue

Я использую FormArray в реактивной форме angular, и все работает нормально, пока я не попытаюсь выполнить операцию patchValue ().

Здесь я пытаюсь отредактировать projectForm. В форму вы можете добавить нескольких разработчиков из <select> <option> </option> </select>. Значение в поле параметра взято из базы данных, и пользователь может добавить любое количество разработчиков по своему усмотрению.

Версия проблемы с упрощенным кодом выглядит следующим образом:
project.component.ts

projectForm: FormGroup

constructor(private fb: FormBuilder, private projectService: ProjectService, private developerService: DeveloperService){ }

ngOnInit() {
    this.developerService.getDeveloper().subscribe((data) => {
        this.developers = data;
    }, (error) => {
        console.log(error)
    } 
    });

    this.projectForm = this.fb.group({
        project_name: [''],
        devs: this.fb.array([this.buildDevs()]),
    })
    this.editProject();
}

buildDevs(): FormGroup {
    return this.fb.group({
      developer: ['', Validators.required]
    });
  }

displayProject(id: number) {
    this.projectService.getProjectDetail(id).subscribe(
        (project) => this.editProject(project),
        (error) => console.log(error)
    )
}

editProject(project){
    this.projectForm.patchValue({
       project_name: project.project_name, 
    });
    this.projectForm.setControl('devs', this.fb.array(project.developer || []));
}

ProjectService отвечает правильным ответом по проекту. В этом нет ничего плохого.
Добавить и обновить сообщения нужно делать в одной и той же форме, и добавление формы работает нормально. `project.component.html '

<form [formGroup]="projectForm">

    <label>Name: </label>
    <input type="text" formControlName="project_name">

    <label> Developers: </label>
    <div formArrayName="devs">
        <div *ngFor="let d of projectForm.controls.devs.controls; let i = index" [formGroupName]="i">
             <select formControlName="developer" *ngIf="developers">
               <option *ngFor="let dev of developers" value="{{ dev.id }}">{{ dev.user.username }}
               </option> 
             </select>   
        </div>
    </div>
</form>

Following error in the console is present in the response whenever I visit the project edit route
 ошибка в консоли
Номер поля параметра точно соответствует количеству разработчиков, связанных с проектом, которые нужно отредактировать, но имя пользователя разработчика не отображается в вариант.
ERROR Error: Cannot find control with path: 'devs -> 0 -> developer'
ERROR Error: Cannot find control with path: 'devs -> 1 -> developer' so on ... as the number of developer ...
Мы будем благодарны за любую помощь, так как я новичок в angular и перепробовал все возможные варианты, которые я могу сделать. Спасибо.


person dipesh    schedule 26.06.2019    source источник
comment
Замените в HTML projectForm.controls.devs.controls на devs.controls. Будет полезно, если вы предоставите stackblitz такие запросы. Это поможет другим разработчикам быстро найти проблему и быстрее решить ее для вас.   -  person r2018    schedule 26.06.2019


Ответы (2)


вам необходимо инициализировать FormArray необходимым количеством элементов управления перед использованием patchValue.

предполагая, что project.developer является Array of Objects в этой форме на основе вашего кода

[{developer: "dev1"},{developer: "dev2"},{developer: "dev3"}]
  editProject(project) {
    const devs = this.projectForm.get("devs") as FormArray;
    devs.clear();
    project.developer.forEach(d => devs.push(this.buildDevs()));
    this.projectForm.patchValue({
      project_name: project.project_name,
      devs: project.developer
    });
  }
person ysf    schedule 26.06.2019
comment
Я использую это в поле <select> </select и использую это решение, точное количество поля <select> </select> отображается без каких-либо ошибок, но значение не выбрано, я думаю, что значение id из ответа необходимо для отображения выбранного значения поля. - person dipesh; 26.06.2019
comment
Ответ в формате [{id: 1, detail: 'detail-1'}, {id:2, detail: 'detail-2'}] - person dipesh; 26.06.2019
comment
затем преобразуйте его в формат, ожидаемый вашей формой, следующим образом devs: project.developer.map(pd => ({developer: pd.id})) - person ysf; 26.06.2019
comment
я рад, что это помогло. хорошего дня :) - person ysf; 26.06.2019

Я использовал patchModelValue метод @rxweb/reactive-form-validators, он обновит значение FormControl внутри FormGroup на основе предоставленного объекта JSON сервера или объекта модели. Он обновит конкретное значение FormControl из FormGroup. Вы можете передать project.developer во время вызова API редактирования проекта.

export class UserComponent implements OnInit {
    userInfoFormGroup: RxFormGroup

    constructor(
        private formBuilder: RxFormBuilder    ) { }

    ngOnInit() {
      this.userInfoFormGroup = <RxFormGroup>this.formBuilder.group({      
          devs:[
          {
            developer:['',Validators.required]
          }]
        });
    }
 getFormArray(){
      let formarray = this.userInfoFormGroup.controls.devs as FormArray;
      return formarray.controls;
    }

    editProject()
    {
          this.userInfoFormGroup.patchModelValue( {
                devs: [{ developer: "John" }] });
    }
}

Вам просто нужно импортировать RxFormBuilder в свой компонент и RxReactiveFormsModule в модуль приложения ts

См. Этот рабочий пример

person Ushmi Dave    schedule 26.06.2019
comment
Я действительно новичок в Angular, и я мало знаю о patchModelValue, моя проблема теперь исправлена ​​после следующего ответа. Ваша помощь очень ценится, спасибо :) - person dipesh; 26.06.2019