Динамические c социальные ссылки в Angular 8 с использованием реактивных форм - PullRequest
3 голосов
/ 20 января 2020

Я пытаюсь отобразить список динамических c социальных ссылок в моем приложении Angular. Данные поступают из базы данных следующим образом:

// User model
{
    ...
    socialLinks: [
       { name: 'Site1', url: 'https://site1.com/user' },
       { name: 'Site2', url: 'https://site2.com/user' },
       ...
    }
    ...
}

Так создается группа форм в компоненте:

public async ngOnInit(): Promise<any> {
    const userResult = await this.userService.getLoggedInUser();

    if (userResult) {
        this.userSettingsForm = this.fb.group({
            displayName: [this.user.displayName, Validators.required],
            bio: [this.user.bio, Validators.maxLength(256)],
            location: [this.user.location],
            socialLinks: this.fb.group(this.user.socialLinks)
        });
    }
}

И шаблон:

<form [formGroup]="userSettingsForm" (ngSubmit)="submitForm()">
    ...
    <div *ngFor="let socialLink of user.socialLinks; let index = index" formArrayName="socialLinks">
        <div class="position-relative">
            <img [src]='"/assets/icons/" + user.socialLinks[index].name + ".svg"' 
                [alt]='user.socialLinks[index].name + " page"'>
            <input class="form-control" [formControlName]='index'
                [value]='user.socialLinks[index].url'>
        </div>
    </div>
</form>

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

Stackblitz

Заранее спасибо!

1 Ответ

1 голос
/ 21 января 2020

Например, socialLinks - это массив - вам нужно отразить его с помощью класса FormArray , а элементы массива будут FormGroup экземпляры. Мы могли бы добиться этого с помощью существующего построителя форм, просто отображая ссылки:

socialLinks: this.fb.array(this.user.socialLinks.map((l) => this.fb.group(l)))

после этого шага мы получили бы массив форм с для групп, представляющий структуру socialLink , так что Вот почему нам также нужны изменения в html для его покрытия (из стекаблица):

<div class="position-relative" [formGroupName]='index'>
    ...
    <input class="form-control" formControlName='url'>
</div>

теперь каждый [formGroupName] будет иметь значение, а index и formControlName будут представлять поле, с которым мы хотим работать

Надеюсь, это поможет:)

Также здесь есть несколько полезных объяснений:

https://alligator.io/angular/reactive-forms-formarray-dynamic-fields/

Когда использовать FormGroup или FormArray?

PS рассмотрите возможность использования socialLink внутри *ngFor, так как это прямая ссылка на user.socialLinks[index]

...