0

我正在写一个“有趣”的 Scala/Scala.js项目。

在我的服务器上,我有uuid-s 引用的实体(在Ref -s 内)。

为了“有趣”,我不想使用flux/redux架构,但仍然在客户端使用React(使用ScalaJS-React)。

我想做的是拥有一个简单的缓存,例如:

  • 当 ReactUserDisplayComponent想要显示Entity Useruuid=0003
  • 然后该render()方法调用Cache(作为 a 传入prop
  • 让我们假设这是第一次UserDisplayComponent要求这个特定的User(with uuid=0003) 并且Cache还没有它
  • 然后从服务器Cache获取AjaxCallUser
  • AjaxCall返回Cache触发器时re-render
  • 但 !现在,当组件请求Userfrom theCache时,它​​会立即User Entity从 the获取,Cache并且不会触发AjaxCall

我想实现的方式如下:

  • 我开始一个render()
  • 里面的“东西”render()要求Cache各种Entities
  • Cache返回其中一个LoadingEntity本身。
  • 在渲染结束时,Cache将所有AjaxRequest-s 发送到服务器并等待它们全部返回
  • 一旦所有AjaxRequests都返回(让我们假设它们返回 - 为了简单起见)Cache触发一个“ re-render()”,现在所有之前请求的实体都Cache立即提供。
  • 当然,新到达的Entity-s 可能会触发render()获取更多Entity-s 如果例如我加载一个Entity例如case class UserList(ul: List[Ref[User]])类型的。但是我们现在不用担心这个。

问题:

1)如果我以这种方式处理状态,我真的做错了吗?

2)是否有一个已经存在的解决方案?

我环顾四周,但一切都是 FLUX/REDUX 等......沿着这些思路...... - 为了:

  • “乐趣”
  • 好奇心
  • 勘探
  • 玩弄
  • 我认为这个简单的缓存对于我的用例来说会更简单,因为我想以一种简单的方式将基于“REF”的“域模型”传递给客户端:就好像客户端在服务器上并且网络将是无限的快速和零延迟(这是缓存将模拟的)。
4

1 回答 1

2

考虑构建丰富的动态 Web UI 需要解决哪些问题,以及哪些库/层通常会为您处理这些问题。

1. DOM事件(点击等)需要触发State的变化

这相对容易。DOM 节点公开了基于回调的侦听器 API,可以直接适应任何架构。

2.State的变化需要触发DOM节点的更新

这比较棘手,因为它需要高效且可维护的方式完成。您不想在其状态更改时从头开始重新渲染整个组件,并且您不想编写大量 jquery 样式的意大利面条代码来手动更新 DOM,因为即使效率很高,这也太容易出错运行。

这个问题主要是为什么像 React 这样的库存在,它们将其抽象到虚拟 DOM 后面。但是你也可以在没有虚拟 DOM 的情况下将其抽象出来,就像我自己的Laminar库一样。

放弃对这个问题的库解决方案仅适用于更简单的应用程序。

3.组件应该能够读/写全局状态

这是flux / redux解决的部分。具体来说,除了应用于全局状态而不是组件状态之外,这些都是问题 #1 和 #2。

4.缓存

缓存很难,因为缓存需要在某些时候失效,在上面的所有内容之上。

Flux / redux 根本没有帮助。确实有帮助的库之一是Relay,它的工作原理与您提出的解决方案非常相似,只是方式更复杂,并且位于 React 和 GraphQL 之上。阅读其文档将帮助您解决问题。如果您不需要整个 React / GraphQL 包袱,您绝对可以在纯 Scala.js 中实现中继功能的一小部分,但您需要了解现有技术。

5. 序列化和类型安全

这是此列表中与 Scala.js 相关的唯一问题,而不是一般的 Javascript 和 SPA。

Scala 对象需要序列化才能通过网络传输。进入 JSON、protobufs 或其他任何内容,但您需要一个不会涉及容易出错的手动工作的系统。有许多 Scala.js 库可以解决这个问题,例如 upickle、Autowire、endpoints、sloth 等。关键词:“Scala JSON 库”或“ Scala 类型安全 RPC ”,取决于您想要哪种解决方案。


我希望这些原则足以作为答案。当您了解这些问题时,您的解决方案是否适用于给定的用例应该是显而易见的。实际上,您没有描述您的解决方案如何解决问题 2、4 和 5。您可以使用我提到的一些库或使用类似的想法/算法实现您自己的解决方案。


在一个小的技术说明中,考虑为你的缓存层实现一个异步的、基于 Future 的 API,以便它返回Future[Entity]而不是Loading | Entity.

于 2018-12-18T06:19:58.080 回答