在redux / ngrx存储应用程序体系结构

时间:2017-04-20 13:05:53

标签: angular typescript redux ngrx

背景

团队正在使用Angular和@ngrx库构建一个基于REST的大型Web应用程序,用于状态管理。

我们希望将服务器中的实体建模为TypeScript类。这些可能是:帐户,用户等

这实现了:

  • 与API的松散耦合;如果响应发生变化,则只有模型必须更改
  • 封装基本功能,例如要生成fullName
  • 的名字和名字的字符串连接

不确定性在于,在应用程序的时间线期间,初始化模型时,调用:new Account(accountResponse)

传统逻辑建议尽可能早地在服务中执行此操作,以便检索帐户(无论是缓存,服务器响应等)。

this.apiService.fetch(AccountService.URL)
      .map(accounts => accounts.map((a: AccountResponse) => new Account(a)));

此方法由ngrx效果调用,然后在成功响应之后,减少器将Account对象添加到存储中。

但这有效... ngrx / redux“best practice”表示只应将普通对象和基元保存在商店中,以便于序列化以及其他原因。

要遵守此建议,初始化Account对象必须更进一步。无论是在单个组件中,还是在state selector中,或者通常在使用帐户的任何位置。

这对我来说没有意义,因为原始帐户响应对象正在应用程序中传递,这在一定程度上打败了将它们包装在模型中的重点。

该应用程序在结构上类似于@ngrx/example书籍应用程序,鉴于其简单性,它不会将服务器响应包装在模型对象中。

问题:

  • 在商店中保留初始化课程有什么不利影响?

  • 如果要在商店中保留普通对象,那么数据流中的哪个模型应该class来初始化?

3 个答案:

答案 0 :(得分:1)

使用ngrx的最简单方法是将其视为数据库,而不仅仅是javascript共享对象缓存。您不会像ngrx一样将javascript助手存储在数据库中。

您可以停止使用模型函数,而在需要时使用实用程序方法,或者可以使用可观察的运算符包装选择器结果。虽然类似state.pipe(select(mySelector), myWrapFunction)之类的东西,但是每次都会重新创建包装器。

您可能希望查看视图模型设计模式(例如[MVVM](https://en.m.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel),以查看与您尝试执行的操作类似的方法。

答案 1 :(得分:0)

请检查此example,以了解如何初始化ngrx存储中的功能状态。我希望这就是您要寻找的。

答案 2 :(得分:0)

@kyranjamie我正在尝试了解如何以最佳实践的方式进行操作。我了解您正确吗?您将一个普通对象存储在一个状态中。当组件需要状态中的对象时,它将使用服务,例如: HomeService -获取HomeModel对象而不是普通对象

@Injectable({
  providedIn: 'root'
})
export class HomeService {

  constructor() {
  }

  public getSelectedHome(homeObject: HomeJSON) {
    return Object.assign(new HomeModel(), homeObject);
  }
}

一个组件需要订阅状态。它订阅了状态更改,但不是直接使用状态普通对象,而是使用HomeService将普通对象变成类对象(HomeModel)。

ngOnInit() {
    this.store.pipe(select(getSelectedHome)).subscribe(
      home => {
        this.home = this.homeService.getSelectedHome(home);
      }
    );
  }

这是怎么做的?