gpt4 book ai didi

Angular 保存/恢复组件状态

转载 作者:行者123 更新时间:2023-12-02 10:48:25 32 4
gpt4 key购买 nike

我正在开发一个具有多选项卡布局的 Angular 7 应用程序。每个选项卡都包含一个组件,该组件可以引用其他嵌套组件。

当用户选择一个新的/另一个选项卡时,当前选项卡上显示的组件将被销毁(我不仅仅是隐藏它们,而且我遵循了这种模式,因为打开的选项卡可能很多,这似乎是一个更快的解决方案大部头书)。由于加载组件的成本可能很高(可能需要从 API 检索大量数据),因此我尝试将每个组件状态保留在选项卡容器中(它在整个应用程序生命周期中保持事件状态)。

一切都按预期工作,但我认为我已经使用了很多代码来满足我的需求,我希望一切都可以更简单(并且不太容易出错)。

下面是关于我如何做到这一点的摘录。首先,我创建了一个抽象类,选项卡中的每个组件都应该扩展它。

export abstract class TabbedComponent implements OnInit, OnDestroy {
abstract get componentName(): string;

tab: LimsTab;
host: TabComponent;
private _componentInitialized = false;

constructor(
private _host: TabComponent,
) {
this.host = _host;
}

get componentInitialized(): boolean {
return this._componentInitialized;
}

ngOnInit(): void {
this.tab = this.host.tab;
this.loadDataContext();
this._componentInitialized = true;
}

ngOnDestroy(): void {
this.saveDataContext();
}

get dataContext() {
return this.tab.dataContext;
}

protected abstract saveDataContext(): void;
protected abstract loadDataContext(): void;
}

loadDataContextsaveDataContext在具体组件中实现,并包含保存/检索组件实例值的逻辑。而且我用过 _componentInitialized了解码件何时调用其生命周期钩子(Hook) OnInit:组件可以从其父组件接收 @Inputs 和 ngOnChangesOnInit之前触发据我所见。

下面是具体实现的示例:

@Component({
...
})
export class MyComponent extends TabbedComponent implements OnChanges {

private qualityLotTests: QualityLotTestListItem[];
private _selectedTest: QualityLotTestListItem;

@Input()
selectedQualityLot: string;

@Output()
selectedTest: EventEmitter<QualityLotTestListItem> = new EventEmitter<QualityLotTestListItem>();

constructor(_host: TabComponent, private qualityLotService: QualityLotService) {
super(_host);
}

get componentName(): string {
return 'QualityLotTestListComponent';
}

ngOnChanges(changes: SimpleChanges): void {
if (this.componentInitialized) {
// before calling loadData I need to restore previous data (if any)
// this allow me to undestrand if loaded data filters has changed
// I know I restored it if onInit has executed

// if componentInitialized -> onInit has been executed and input parameters passed from parent are changed
this.loadData();
}
}

protected saveDataContext(): void {
this.dataContext[this.componentName].selectedQualityLot = this.selectedQualityLot;
this.dataContext[this.componentName].state = this.state;
this.dataContext[this.componentName].qualityLotTests = this.qualityLotTests;
this.dataContext[this.componentName].selectedSampleTestIDs
= this.selectedSampleTestIDs;
this.dataContext[this.componentName]._selectedTest = this._selectedTest;

}

protected loadDataContext(): void {
let previouslySelectedQualityLot: string;

if (this.dataContext[this.componentName]) {
previouslySelectedQualityLot = this.dataContext[this.componentName].selectedQualityLot;
this.state = this.dataContext[this.componentName].state || this.state;
this.qualityLotTests = this.dataContext[this.componentName].qualityLotTests;
this._selectedTest = this.dataContext[this.componentName]._selectedTest;
} else {
this.dataContext[this.componentName] = {};
}
this.selectedTest.emit(this._selectedTest);

if (this.qualityLotTests && previouslySelectedQualityLot === this.selectedQualityLot) {
this.dataStateChange(<DataStateChangeEvent>this.state);
} else {
this.loadData();
}
}


loadData(): void {
if (this.selectedQualityLot) {
this.loading = true;
this.qualityLotService
.getQualityLotTests(this.selectedQualityLot)
.subscribe(
qualityLotTests => {
this.qualityLotTests = qualityLotTests;
this.gridData = process(this.qualityLotTests, this.state);
this.loading = false;
},
error => (this.errorMessage = <any>error)
);
} else {
this.qualityLotTests = null;
this.gridData = null;
this.state = {
skip: 0,
take: 10
};
this.selectedSampleTestIDs = [];
this.selectedTest.emit(null);
}
}

public dataStateChange(state: DataStateChangeEvent): void {
this.loading = true;
this.state = state;
this.gridData = process(this.qualityLotTests, this.state);
this.loading = false;
}
}

您认为我可以如何改进上面的代码?

我已在此处加载了我的应用程序的摘录 https://stackblitz.com/edit/angular-tabbed-app

最佳答案

我们可以看一下 Plunkr 来进行澄清吗?

我认为您可以利用三种常见模式来保持状态,而无需所有对象继承。

  1. 容器/表示(也称为智能和哑)组件

在这里,您将获取数据并将其存储在容器组件中,并通过@Input()将它们传递给演示组件。您可以在此处销毁演示组件,而不必担心丢失状态。

  • 路由器导航
  • 最好使用路由器导航的概念来显示所需的容器组件,不仅可以利用现有实践,还可以让用户始终知道他们在应用程序中的位置。

  • 最重要的一个——状态管理库——我用NgRx但听说过关于Akira的好消息和 NGXS
  • 如果您从未使用过,则有一定的学习曲线使用 Redux 模式,您可以将应用程序状态存储在一个位置,使其不可变并从任何组件引用它。

    关于 Angular 保存/恢复组件状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56103263/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com