Angular * ngFor将其中一个组件中受影响的更改传播到所有剩余组件

时间:2018-01-08 00:49:08

标签: angular angular5 angular-components

那里好人,你好 所以我决定创建一个自定义组件,然后我将在Angular应用程序的不同部分使用它。

以下是我的组件的样子:

import {
    Role,
    MEMBER_ROLES
} from './role';

@Component({
    selector: 'app-role-chooser',
    template: 'app-role-chooer.component.html'
})
export class RoleChooserComponent, 
    implements OnInit, OnDestroy {

    allRoles = MEMBER_ROLES;
    unSelectedRoles: Role[];
    selectedRoleId: string;

    // roles which has been assigned to this user
    @Input()
    selectedRoles: Role[];
    // user value from roles
    @Input()
    userId: string;
    // wheather we should commit changes to the server
    // or just return an update
    @Input()
    commitChanges = false;

    // notify other components when role has been removed
    @Output()
    onRemove = new EventEmitter<Role>();

    // notify other components when role has been added
    @Output()
    onAdd = new EventEmitter<Role>();

    // the flag to signal that "we're busy committing changes"
    committing = false;

    constructor() {}

    private _updateRoles() {
        // retain roles which have not been selected
        this.unSelectedRoles =
            this.allRoles.filter(role =>
                this.selectedRoles.indexOf(role) === -1);
        // console.log(this.unSelectedRoles);
    }

    private _fireUpdate(roleId: string, isAdded: boolean) {
        const roles = 
           (isAdded ? this.unSelectedRoles : this.selectedRoles);
        const index = roles
            .map(role => role.id)
            .indexOf(roleId);

        if (index !== -1) {
            const changed = roles[index];
            if (isAdded) {
                this.selectedRoles.unshift(changed);
                this.unSelectedRoles.splice(index, 1);
                this.onAdd.emit(changed);
            } else {
                this.selectedRoles.splice(index, 1);
                this.unSelectedRoles.unshift(changed);
                this.onRemove.emit(changed);
            }
        }
    }

    removeRole(roleId: string) {
        // check if we should commit changes
        if (this.commitChanges) {
            if (!this.userId) {
                throw new Error(
                  'commitChanges option requires ' + 
                  'that you also supply userId!');
            }
            // TODO: commit changes to the server.
            this.commiting = true;
        } else {
            // TODO: this code should real come 
            // after user role has been changed
            this._fireUpdate(roleId, false);
        }
    }

    acceptRole() {
        // console.log(this.selectedRoleId);
        if (this.commitChanges) {
            if (!this.userId) {
                throw new Error(
                    'commitChanges option requires ' + 
                    'that you also supply userId!');
            }
            // TODO: commit changes to the server.
            this.commiting = true;
        } else {
            // TODO: this code should real come
            // after user role has been changed
            this._fireUpdate(this.selectedRoleId, true);
        }
        // this.togglePopup();
    }

    ngOnInit() { this._updateRoles(); }
    ngOnDestroy() {
        this.allRoles.length = 0;
        this.selectedRoles.length = 0;
        this.unSelectedRoles.length = 0;
        this.onAdd.unsubscribe();
        this.onRemove.unsubscribe();
    }
}

然后,在我的角度应用程序的某个地方,我尝试在另一个组件中使用它,下面的代码段是我的用法。

<tr *ngFor="let user of users">
    <td nz-td>
         <app-role-chooser
            (onRemove)="onRemoved()"
            (onAdd)="onAdded()"
            [userId]="user.id"
            [selectedRoles]="[]">
         </app-role-chooser>
    </td>
 </tr>

因此,该组件工作正常,但事实是如果我选择或删除一个项目,整个项目列表&#39; NgFor指令下的组件也会受到影响,就像我进行批量更新一样,我没有这样做!

下面的屏幕截图说明了我试图解决的问题。 enter image description here

任何可以提供帮助的人。我真的很感激!

1 个答案:

答案 0 :(得分:0)

我终于得到了答案。刚刚意识到我错过了使用该组件。我曾经将[selectedRoles] attr(在整个父组件中可见)绑定到一个值(Did angular创建一个隐式变量?)。相反,我应该做的是在*ngFor

中为每次迭代使用不同的实例
<tr *ngFor="let user of users">
<td nz-td>
     <app-role-chooser
        (onRemove)="onRemoved()"
        (onAdd)="onAdded()"
        [userId]="user.id"
        [selectedRoles]="selectedRolesByUserId[user.id]"> <---- this line was an evil
     </app-role-chooser>
</td>