Обнаружение изменений не работает для сложных объектов, используемых в NgFor - PullRequest
0 голосов
/ 31 января 2019

Я использую Angular 7. У меня есть родительский компонент, который получает список пользовательских моделей из API.Когда "get" завершается успешно, он используется вместе с циклом ngFor для внедрения каждого пользователя в дочерний компонент с помощью @input, который будет отображать список пользователей.

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

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

export class ParentComponent {
users: UserModel[];

    ngOnInit() {
       this.userService.getUsers().subscribe(users => {
        this.users = users;
       });
    }

    onSelectAll() {
        for (let user of this.users) {
            user.selected  = true;
        }
    }
}

Родительский компонент имеет следующее в шаблоне:

<tr users-item [index]="i + 1" [user]="user" *ngFor="let user of users; let i = index"></tr>

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

export class ChildComponent {
    @Input() user: UserModel;

    firstname: string;
    lastname: string;
    selected: boolean;

    ngOnChanges() {
        if (this.user) {
            this.firstname = this.user.firstname;
            this.lastname = this.user.lastname;
            this.selected = this.user.selected;
        }
    }
 }

и шаблон дочернего компонента:

<td><input type="checkbox" [checked]="selected"></td>
<td>{{ fullname }}</td>
<td>{{ lastname }}</td>

Ответы [ 2 ]

0 голосов
/ 31 января 2019

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

В вашем случае использования вы можете сделать это, изменив реализацию select all:

onSelectAll() {
    this.users = this.users.map(user => this.mergeUser(user, {selected: true}));
}

private mergeUser(source: UserModel, updated: Partial<UserModel>): UserModel{
   return {...source, ...updated};
}
0 голосов
/ 31 января 2019

Ниже часть кода не понятна.Почему вы передаете входные данные в таблице строк?

<tr users-item [index]="i + 1" [user]="user" *ngFor="let user of users; let i = index"></tr>

И изменения во входных данных могут быть обнаружены SimpleChanges в дочернем компоненте.Вы должны попробовать что-то вроде этого.

  ngOnChanges(changes: SimpleChanges) {
        if (changes.user && changes.user.currentValue) {
            this.firstname = changes.user.currentValue.firstname;
            this.lastname = changes.user.currentValue.lastname;
            this.selected = changes.user.currentValue.selected;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...