問題描述
如何保持 Angular 組件的最新狀態? (How to keep the latest state of Angular components?)
我在主組件中插入了其他幾個:
<app‑tools * ngIf = "type === 'A'"> </app‑tools>
<app‑history * ngIf = "type === 'B'> </app‑history>
<app‑layers * ngIf = "type === 'C'> </app‑layers>
<app‑objects * ngIf = "type === 'D'> </app‑objects>
它們都由條件*ngif
當用戶激活<代碼><應用歷史> </<app‑history> 組件並在其中做一些工作,離開組件後,切換到另一個組件。
然後,在返回組件時,它被初始化再次。
如何在不使用[hidden]
的情況下保存訪問的Angular組件中的最後一個狀態,因為在這種情況下會分配大量內存來加載無人認領的組件?
參考解法
方法 1:
It sounds like you need a state store of some kind to persist the data changes. NgRx is one solution. If you don’t want to use another library you can create your own state service where you would have behavior subjects defined in the service. When you make a change within the tab, you would execute the next method on the subject variable, passing in the data changes as the parameter to the method call. Within the component, you can can access the current value of the subject by ‘.value’ on the subject. Hope this helps.
方法 2:
You can make use two way data‑binding and have your state passed through the parent of app‑history or whatever. Just be careful about naming your input and output properties of childComponent i.e it should always have "Change" appended to its output corresponding property. Something like:
@Input() x;
@Output() xChange = new EventEmitter();
<div>
<app‑history *ngIf = "type === 'B'" [(myState)]="historyState"></app‑history>
</div>
AppHistoryComponent {
@Input() myState;
@Output() myStateChange = new EventEmitter();
changeMyState(newState) {
this.myStateChange.emit(newState);
}
}
In this way you will always have your state their in your ParentComponent's historyState
property
方法 3:
Complete Working Demo on StackBlitz
Here, simple you can use shared singleton service
with @Input()
and @Ouput()
parent child component architecture. I am taking consideration of history component only. First You have one 1. Container Component which is parent of component used for communicating to service only. and rest all are child component which are only receiving and sending input and output using @Input()
and @Output()
.
HTML is of Container Component is...
<div class="form‑group col‑2 m‑1 card d‑flex alert‑secondary justify‑content‑around">
<div class="card‑body justify‑content‑around d‑flex">
<input class="form‑check‑input" #b [(ngModel)]= "ab" type="checkbox" id="b">
<label for="b"> B </label>
</div>
<div class="card m‑1 col‑12 col‑md‑3 alert‑secondary " *ngIf="b.checked">
<app‑history class="card‑body" [stateHistory]="getHistoryState()"
(stateUpdate)="historyStateUpdate($event)" >
</app‑history>
</div>
In <app‑history>
class we have one [stateHistory]
as aInput and one (stateUpdaate)
as a Output.
Your containerComponent.ts
In this component class we inject state‑service using DI of angular.
constructor(private stateService: StateService) { }
getHistoryState(){
return this.stateService.historyState;
}
historyStateUpdate(event){
this.stateService.historyState = event;
this.saved = true;
this.saveNotification();
}
saveNotification(){
setTimeout(() => {
this.saved = false;
}, 2000);
}
Further you can scale here to use rxjs as per your required need.
方法 4:
You should create your own class that implements RouteReuseStrategy
. It caches all or chosen components and prevents them from being re‑created from scratch again and again. As an example you may have a look at AppRouteReuseStrategy
.
Please note that the class needs to be registered as a provider in
app.module.ts
.
providers: [
{ provide: RouteReuseStrategy, useClass: AppRouteReuseStrategy },
方法 5:
You can use [hide] property of angular instead of *ngIf. Doing so you are keeping all the components in the dom but displaying only the current active component by which you will not lose the component state even if it is not displayed.
<app‑tools [hide] = "type !== 'A'"> </app‑tools>
<app‑history [hide] = "type !== 'B'> </app‑history>
<app‑layers [hide] = "type !== 'C'> </app‑layers>
<app‑objects [hide] = "type !== 'D'> </app‑objects>
(by OPV、Paul、Ankit Kaushik、GaurangDhorda、uminder、this is yash)