如何在重构应用程序中分派两个相关事件?

发布于 2025-01-14 23:05:07 字数 728 浏览 4 评论 0原文

我正在开发一款带有库存系统的游戏。现在,角色装备和库存在我的数据库中是单独的值。我的问题是,当用户装备物品时,我需要从库存中删除该物品并将其添加到角色中。

我现在有这样的事情:

(defn equip-item [item idx]
  (re-frame/dispatch [:equip-item {:position :off-hand :item item}])
  (re-frame/dispatch [:remove-item-from-inventory idx]))

(re-frame/reg-event-db
  :equip-item
  (fn [db [_ itemObj]]
    (update-in db [:character :equipment] merge {(:position itemObj) (:item itemObj)})))

(re-frame/reg-event-db
  :remove-item-from-inventory
  (fn [db [_ idx]]
    (update-in db [:inventory :main] handle-remove idx)))

到目前为止,这工作得很好,但我想知道是否有更好的方法来处理像这样分派多个事件?我知道可以使用 :dispatch-n 键创建效果,但我不确定这在这里是否合适。

无论如何,我也担心一个事件失败而另一个事件成功。它们的行为应该有点像一笔交易,如果其中一个失败,那么它们都应该失败。

I'm working on a game with inventory system. Right now, the characters equipment and inventory are separate values in my DB. My problem, is when a user equips an item I need to both remove the item from the inventory and add it to the character.

I have something like this right now:

(defn equip-item [item idx]
  (re-frame/dispatch [:equip-item {:position :off-hand :item item}])
  (re-frame/dispatch [:remove-item-from-inventory idx]))

(re-frame/reg-event-db
  :equip-item
  (fn [db [_ itemObj]]
    (update-in db [:character :equipment] merge {(:position itemObj) (:item itemObj)})))

(re-frame/reg-event-db
  :remove-item-from-inventory
  (fn [db [_ idx]]
    (update-in db [:inventory :main] handle-remove idx)))

This works perfectly fine so far, but I'm wondering if there's a better way to handle dispatching multiple events like this? I know there's an ability to create an effect with a :dispatch-n key, but I'm not sure if that's appropriate here.

In any case, I'm also concerned about one event failing with the other succeeding. These should behave sort of like a transaction in that if one fails they both should fail.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

万劫不复 2025-01-21 23:05:07

不要使用 reg-event-db,而是使用 reg-event-fx。这将返回效果的哈希值。

这些效果之一可以是 :fx,它是要调用的其他效果的列表。例如,这些效果可以是调度事件。一些代码:

(rf/reg-event-db
 :print1
 (fn [db]
   (.log js/console "print1!")
   db))

(rf/reg-event-db
 :print2
 (fn [db]
   (.log js/console "print2!")
   db))

(rf/reg-event-fx
 :test-two-dispatch
 (fn [{:keys [db]} _]
   {:db db
    :fx [[:dispatch [:print1]]
         [:dispatch [:print2]]]}))

Instead of using reg-event-db, use reg-event-fx. This returns a hash of effects.

One of these effects can be :fx, which is a list of other effects to call. These effects can be, for example, to dispatch an event. Some code:

(rf/reg-event-db
 :print1
 (fn [db]
   (.log js/console "print1!")
   db))

(rf/reg-event-db
 :print2
 (fn [db]
   (.log js/console "print2!")
   db))

(rf/reg-event-fx
 :test-two-dispatch
 (fn [{:keys [db]} _]
   {:db db
    :fx [[:dispatch [:print1]]
         [:dispatch [:print2]]]}))
温折酒 2025-01-21 23:05:07

最好的方法是提取这些update-in以分离常规函数,创建必要的第三个事件,并通过例如->调用其中的这些函数。当然,您也可以在原始事件中调用这些函数,而不是 update-in

The best approach would be to extract those update-in to separate regular functions, create the necessary third event, and call those functions in there via e.g. ->. Of course, you would call those functions in the original events instead of update-in as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文