如何用Hotwire构建动态仪表板(第二部分)

237 阅读2分钟

第一部分中,我们建立了一个管理面板,并使用Turbo Streams来实现收入动态化。在这篇文章中,我们将继续建立管理面板。我们将使用Turbo Frames实现标签,然后通过使 "实时订单 "动态化来结束。

涡轮框架标签

首先,我们将更新现有的显示收入的逻辑。我们将把它包在一个 turbo_frame_tag块中,并将其称为 "tab_data".这个标签是Turbo在改变标签时用来替换内容的。我们所要做的就是在控制器中渲染一个新的 "tab_data"框架,从一个控制器中。

此外,我们将更新部分内容,使其更加通用。

index.html.erb

1
2
3
4
5
6
<%= turbo_frame_tag "tab_data" do %>
  <%= turbo_stream_from "revenue" %>
  <div id="data">
    <%= render partial: 'metrics/financial_data', locals: { data: @revenue } %>
  </div>
<% end %>

metrics/_financial_data.html.erb

1
2
3
<div id="data">
  <%= number_to_currency(data) %>
</div>

在第一部分,我们创建了存根按钮来控制标签。为了让它们工作,我们需要添加新的路由:

1
2
3
4
5
6
  resource :dashboard do
    member do
      get :revenue
      get :orders
    end
  end

通过创建的路由,我们可以更新按钮的链接:

1
2
<%= button_to "Real time revenue", revenue_dashboard_path, method: :get %>
<%= button_to "Real time orders", orders_dashboard_path, method: :get %>

这些链接需要一个控制器,我们可以为 "收入 "和 "订单 "生成一个动作:

1
bin/rails g controller DashboardsController revenue orders

在控制器的动作中,我们最终想呈现一个 "tab_data"Turbo框架,就像索引页上的那个。我们将把Turbo Frame的代码放在一个局部中,然后从控制器中渲染。我们还将使用 turbo_frame_request?来确保这个局部只对Turbo Frame请求进行渲染。

每个标签的渲染逻辑是相似的,但又有足够的不同,以证明两个不同的范本。这些参数将包含Turbo Frame和Turbo Stream代码。控制器只需要传入要显示的数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  def revenue
    if turbo_frame_request?
      respond_to do |format|
        format.html { render partial: 'dashboards/revenue_tab',
          locals: { data: Sale.total }}
      end
    else
      # do something else
    end
  end

  def orders
    if turbo_frame_request?
      respond_to do |format|
        format.html { render partial: 'dashboards/orders_tab',
          locals: { data: Sale.count }}
      end
    else
      # do something else
    end
  end

接下来我们需要建立参数。外部块创建了一个Turbo Frame标签,它提供了标签行为。内部块定义了一个Turbo Stream订阅,它允许指标的实时更新。

revenue_tab.html.erb

1
2
3
4
5
6
<%= turbo_frame_tag "tab_data" do %>
  <%= turbo_stream_from "revenue" %>
  <div id="revenue">
    <%= number_to_currency(data) %>
  </div>
<% end %>

orders_tab.html.erb

1
2
3
4
5
6
<%= turbo_frame_tag "tab_data" do %>
  <%= turbo_stream_from "orders" %>
  <div id="orders">
    <%= data %>
  </div>
<% end %>

现在Turbo框架的实现是端到端的工作。Turbo将处理所有更新标签的魔法。

让实时订单工作

要完成动态仪表盘,还需要最后一个改动。在第一部分中,我们让 "收入 "工作,但没有完成 "订单"。为了解决这个问题,我们需要添加一个额外的 after_commit来广播订单的更新。我们将使用 Sale.count来表示订单。

sale.rb

1
after_commit -> { broadcast_update_to "orders", partial: "metrics/data", locals: { data: Sale.count }, target: "orders" }

最后,我们需要添加一个小的局部,包含我们要广播的代码块。

metrics/_data.html.erb

1
2
3
<div id="data">
  <%= data %>
</div>

就这样了!谢谢你的阅读。我们希望你喜欢这两部分的Hotwire系列,包括Turbo Streams和Turbo Frames。