那里好人,你好 所以我决定创建一个自定义组件,然后我将在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
指令下的组件也会受到影响,就像我进行批量更新一样,我没有这样做!
任何可以提供帮助的人。我真的很感激!
答案 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>