2

我正在尝试重构 Aurelia 应用程序以使用 Aurelia Store 插件,而不是注入到我的所有视图模型类的单例类。在我当前的应用程序中,有一堆服务类可以进行 ajax 调用以从 web api 获取数据。在调用时使用承诺链很容易在加载内容时暂停 UI,例如

this.isLoading = true;
this.api.getStuff()
  .then(s => this.myproperty = s.stuff)
  .catch(a => console.error("hgssgg"))
  .finally(() => this.isLoading = false);

现在我已经将 API 调用移到了我的商店操作中,我如何在我的 UI 中表示这种加载?

为基本问题道歉。任何帮助深表感谢。

4

2 回答 2

2

这是一个非常好的方法。通常,只要该功能仅由单个组件使用,您应该更喜欢本地状态而不是全局(插件)状态。因此,如果您让我们说一个元素是唯一负责渲染加载器图像的组件,那么通过 property 将其仅保留在该组件的本地当然是一种好方法isLoading

现在,正如您所提到的,您可能需要从应用程序中的各个位置访问该状态,也就是您想要将其提升为全局状态的时候。或者,这就是将加载器封装在自定义元素中的好处,让消费者有条件地显示加载器元素。最重要的是,将加载状态和加载机制存储在您通过 DI 公开的服务中。

// loading-service.ts
export class LoadingService {
  showLoader: boolean = false;

  public async yourLoadingMechanism() {
    this.showLoader = true;
    await fetchYourDataAsync();
    this.showLoader = false;
  }
}

// consumer-view.ts
export class ConsumerView {
  constructor(loadingService: LoadingService) {}
}

// consumer-view.html
<template>
  <button click.delegate="loadingService.yourLoadingMechanism()>Fetch data</button>
  <status-loader show.bind="loadingService.showLoader"></status-loader>
</template>

我个人认为没有 100% 的这个或那个。使用 store 插件并不一定意味着您必须全力以赴进行全局状态管理,而是可以并且应该在您认为合适的地方结合使用经典服务。上述方法不仅封装了加载指示器,还帮助您将数据访问重构到一个地方。如果服务本身需要监听状态变化,您甚至可以在其中创建订阅并执行所需的操作。

于 2019-02-11T06:21:22.887 回答
1

我可以调度 3 个动作来实现我想要的,但让我感到震惊的是,这是很多状态变化,只是为了告诉我一个动作需要一些时间。所以,事实上,ui 加载指示器就是这样,告诉我正在进行异步操作。因此,与其将我的 isLoading 属性存储在状态中,我只是将其保留为我的视图模型的属性,并在调度操作时对其进行更改。所以,在我的 viewModel 中是这样的。

this.isLoading = true;
await this.store.dispatch(getStuff);
this.isLoading = false;

有这么糟糕吗?似乎太容易了。我想这仅适用于当前的视图模型。如果我有其他组件需要知道是否正在加载,那么拥有一个任何组件都可以订阅的 state 属性是有意义的。

于 2019-02-11T02:21:27.377 回答