Я пытаюсь динамически добавлять роли в мое приложение пользователя / роли. У меня есть Formarray, где я могу показать роли пользователя в представлении редактирования. И есть кнопка для добавления дополнительных ролей для пользователя. Но когда я нажимаю кнопку «Добавить роль», я получаю это сообщение об ошибке:

Ошибка: невозможно найти элемент управления с путем: 'roleArr -> 1 -> name'

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

Вот мой код:

users-edit.component.html (выдержка)

<div formArrayName="rolesArr" >
<div class="row">
    <div class="col-md-10 col-md-offset-2">
        <button class="btn btn-default"
                type="button"
                (click)="addRole()">Add Role
        </button>
    </div>
</div>
<br>
<div *ngFor="let role of roles.controls; let i=index">
    <div [formGroupName]="i">

        <div class="form-group">
            <label class="col-md-2 control-label" [attr.for]="i">Role</label>

            <div class="col-md-8">
                <input class="form-control"
                        [id]="i" 
                        type="text" 
                        placeholder="Role" 
                        formControlName="name" />
            </div>
        </div>
    </div>
</div>

users-edit.component.ts (выдержка)

addRole() {
    this.roles.push(this.fb.group(new Roles()));
}

ngOnInit(): void {

    this.userForm = this.fb.group({
        username: ['', [Validators.required, Validators.minLength(3)]],
        firstname: ['', [Validators.required, Validators.minLength(3)]],
        lastname: ['', [Validators.required, Validators.minLength(3)]],
        password: ['', [Validators.required, Validators.minLength(10)]],
        rolesArr: this.fb.array([])
    });

    this.sub = this.activeRoute.params.subscribe(
        params => {
            let id = +params['id']; //converts string'id' to a number
            this.getUser(id);
        }
    );
}
getUser(id: number) {
        this.userService.getUser(id).subscribe(
                user => this.onUserRetrieved(user)
            );
}
onUserRetrieved(user: User): void {
    console.log("OnUserRetrieved: " + user.firstname);
    if (this.userForm) {
        this.userForm.reset();
    }
    this.users = user;

    if (this.users.id === 0) {
        this.pageTitle = 'Add User';
    } else {
        this.pageTitle = `Edit User: ${this.users.username}`;
    }

    //Update the data on the form
    this.userForm.patchValue({
        username: this.users.username,
        firstname: this.users.firstname,
        lastname: this.users.lastname,
        password: this.users.password
    });

    const roleFGs = this.users.roles.map(roles => this.fb.group(roles));
    const roleFormArray = this.fb.array(roleFGs);
    this.userForm.setControl('rolesArr', roleFormArray);
}

Что я делаю неправильно?

4
Beytullah Güneyli 27 Май 2017 в 21:26

2 ответа

Лучший ответ

Вы должны создать группу форм с элементами управления для Roles, как показано ниже,

createRole() :  FormGroup {
    return this.fb.group({
            name: '',
            type: '',

    });
}

Тогда вы должны нажать на роль, как показано ниже,

addRole() {
    this.roles.push(this.createRole());
}
2
Aravind 27 Май 2017 в 18:54

Хотя ответ Аравинда работает, вы все равно можете делать то же, что и сейчас:

addRole() {
    this.roles.push(this.fb.group(new Roles()));
}

Но элемент управления требует значений по умолчанию для ваших свойств в классе (что именно то, что делает решение Аравинда, он создает объект со значениями по умолчанию)

Так что если ваш текущий класс Roles выглядит примерно так:

export class Roles {
    public name: string;
    public type: string;
}

Вы должны добавить значения по умолчанию, как это:

export class Roles {
    public name: string = '';
    public type: string = '';
}

Это позволяет Angular найти ваши свойства в качестве контроля

Дополнительная информация: https://angular.io/ руководство / реакционноспособные -формы # использование - formarray - к -настоящее - ан- массив из - formgroups

1
Florian K 30 Апр 2018 в 13:05