gpt4 book ai didi

Angular:观察两个状态但只执行一次

转载 作者:行者123 更新时间:2023-12-04 07:59:02 26 4
gpt4 key购买 nike

我的组件观察两种状态(在可观察的商店中):selectedCarviewConfig .当这些状态中的任何一个更新时,我需要运行 showCar()显示具有新配置的汽车。但是,当这两个状态都更新时,例如在初始化时,showCar()应该只运行一次。
代码如下:

    this.selectedCarStore.state$
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(state => {
this.selectedCar = state.selectedCar;
this.showCar();
});

this.configStore.state$
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(_state => {
this.viewConfig = state.viewConfig;
this.showCar();
});

showCar() {
if (this.viewConfig != null || this.selectedCar != null) return;

// update UI with selected car and view config
}

最佳答案

您的 car 的展示有两个来源:selectedCarviewConfig .我们可以设计一个 observable,它只会在这两个数据都可用并且当它们中的任何一个发生变化时才会发出。 combineLatest 运算符是完美的:
所以现在,我们只有一个,而不是两个单独的订阅!

ngOnInit() {
combineLatest([
this.selectedCarStore.state$,
this.configStore.state$]
).pipe(
takeUntil(this.ngUnsubscribe)
)
.subscribe(([carState, config]) => {
this.allCars = carState.allCars;
this.selectedCar = carState.selectedCar;
this.viewConfig = config.viewConfig;
this.showCar();
});
}
以上代码在 subscribe块只会在 selectedCarStore.state$ 时发出和 configStore.state$至少发射过一次。
看看这个工作 StackBlitz ;查看当您选择不同的 View 配置或选择不同的汽车时 View 是如何更新的。
这实现了您的目标……但我们可以使代码更好(更简单)!

如果我们看看您对 showCar() 的评论方法:
// update UI with selected car and view config
这有点暗示我们以前没有以声明式/响应式(Reactive)方式构建代码。现在我们已经设计了一个可以在我们想要的时候发出的流,有了所有必要的数据,我们不需要“手动”检查一个函数来更新 View 。我们的 View 会自动更新,因为我们的流在适当的时间发出。任何时候任何一个源发出一个新值, View 都会自动更新! :-)
注意我们如何将状态复制到我们的组件中:
this.allCars     = carState.allCars;
this.selectedCar = carState.selectedCar;
this.viewConfig = config.viewConfig;
这其实是没有必要的。我们可以将 View 所需的所有数据保留为可观察对象,而不是订阅我们的组件。所以而不是:
public viewConfig: ViewConfig;
public selectedCar: Car;
public allCars: Car[];
我们可以做的:
  private viewConfig$ = this.configStore.state$.pipe(
map(state => state.viewConfig)
);
private selectedCar$ = this.selectedCarStore.state$.pipe(
map(state => state.selectedCar)
);
public selectedCarVm$ = combineLatest([this.selectedCar$, this.viewConfig$]).pipe(
map(([car, config]) => ({car, config}))
);
public allCars$ = this.selectedCarStore.state$.pipe(
map(state => state.allCars)
);
public那些是 View 所需要的。我用了 Vm selectedCar区分数据的后缀以及我们设计为仅在数据和配置都可用时才发出的 View 模型。
注意,我们在我们的类中定义了这些可观察流,我们不再需要在 ngOnInit 中这样做.我们也不再需要订阅,因为我们可以使用 async在我们的模板中使用管道。
  <div *ngIf="selectedCarVm$ | async as selected"
[ngStyle]="{'background-color': selected.config.bgColor }"
[class.large]="selected.config.size === 'large'"
>
{{ selected.car.year }} {{ selected.car.make }} {{ selected.car.model }}
</div>
意味着我们不再需要管理退订,因此我们可以摆脱 ngOnDestroy , ngUnsubscribe主题以及我们所有的 takeUntil !
请比较您的 Original Code 之间的代码> First Solution > 和这个 Reactive Solution .
每一步都减少了代码并简化了逻辑。
我希望这有助于向您展示如何设计流以在所需的时间发出,并将数据保持在可观察的形式以减少代码量(和复杂性)。
干杯! :-)

关于Angular:观察两个状态但只执行一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66551589/

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