我正在使用angular 4,并且正在使用ngrx进行全局状态管理。
我有一些可以渲染多个子组件的组件:
<div upload-list-item *ngFor="let upload of (uploads | async).items" [upload]="upload"></tbody>
我想存储项目视图是否在本地组件的状态下展开。如果我对此有反应,那么此值将存在:
@Component({
// tslint:disable-next-line
selector: '[upload-list-item]',
template: `
<tr class="top-level" (click)="setExpanded()">
<td>
<a
href="javascript:void(0)"
title="Expand/Collapse Row"
[class]="expanded ? 'datatable-icon-down' : 'datatable-icon-right'"
>
</a>
</td>
</tr>
<tr *ngIf="expanded">
<td class="detail-td" colspan="6">
Expanded
</td>
</tr>
`,
styleUrls: ['./upload-list-item.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class UploadListItemComponent {
@Input() upload: Upload;
expanded = false;
setExpanded() {
this.expanded = !this.expanded;
}
}
问题是,每次我更新ngrx存储时,所有本地状态都会消失,或者看起来是这样。
这是预期的行为吗?
答案 0 :(得分:1)
Angular默认情况下不知道已更改了哪个元素,因此它将再次重新渲染整个列表,您的组件被破坏,这就是为什么您失去局部状态的原因。
您可以向ngFor添加trackBy
函数,因此Angular不会重新渲染所有内容,而只修改已更改的组件。不错的帖子here。
<div upload-list-item *ngFor="let upload of (uploads | async).items; trackBy: trackByFn"
[upload]="upload"></tbody>
在您的容器组件中:
trackByFn(index, item) {
return index; // or item.id
}
或者,您可以将每个上载项目的本地状态存储在容器组件中,该组件用于呈现上载项目。
答案 1 :(得分:0)
我不确定是否理解您的疑问。但是,请确保在呈现接口时没有任何操作可更新“上传”状态。每次更新上传时,ngFor指令都会重新渲染界面,您会感觉丢失了更改。我知道发生这种情况是因为您从列表项的每一个中更新了状态,从而修改了整个列表,因此再次呈现了视图。在这种情况下,您可以给ngFor一个trackBy函数,以指定您希望视图如何呈现。