Вещание на несколько турбо-потоков с помощью hotwire
Я правильно подключил hotwire / turbo, чтобы выполнять грубые операции на одной модели в одном месте моей страницы, но я хотел бы обновить ту же модель одновременно в другом месте на моей странице. Я думал, что могу просто настроить два потока, но это не работает.
Указание цели действительно работает для действия create в зависимости от того, как я называю цель, но не для обновления и уничтожения. Это то, что я думаю, должно работать, но не работает:
---- место 1 (поток "существ") ----
<div id="creatures">
<%= turbo_stream_from "creatures" %>
<%= turbo_frame_tag "creatures" do %>
<div>
<% @creatures.each do |creature| %>
<div>
<%= render "creatures/creature", creature: creature %>
</div>
<% end %>
</div>
<% end %>
</div>
---- место 2 (поток "creatures_main") ----
<%= turbo_stream_from "creatures_main" %>
<%= turbo_frame_tag "creatures_main" do %>
<% @creatures.each do |creature| %>
<div>
<%= render "creatures/creature", creature: creature %>
</div>
<% end %>
<% end %>
---- common _creature.html.erb частичный ----
<%= turbo_frame_tag dom_id(creature) do %>
<%= link_to creature.name, "#" %>
<% end %>
---- creature.rb ----
class Creature < ApplicationRecord
validates :name, presence: true
after_create_commit {
broadcast_append_to "creatures"
broadcast_append_to "creatures_main"
}
after_update_commit {
broadcast_replace_to "creatures"
broadcast_replace_to "creatures_main"
}
after_destroy_commit {
broadcast_remove_to "creatures"
broadcast_remove_to "creatures_main"
}
end
Что происходит, когда у меня есть два вызова в моей модели, так это то, что действие create помещает вновь созданное существо в местоположение 1 дважды, только одно из двух обновляется, но оба уничтожаются правильно независимо от того, где они находятся на странице.
1 ответ
creatures
а также
creatures_main
будет именем потока. Вы ищете
target
а также
partial
чтобы контролировать, где поток будет искать для обновления ваших данных и какую часть он будет использовать для обновления.
Можешь попробовать:
after_create_commit -> {
# target here is the ID of the outer div, where data would be appended to
broadcast_append_to "creatures", target: "creatures"`
broadcast_append_to "creatures_main", target: "creatures_main"
}
after_update_commit {
# target here is the ID of each of the creature div
broadcast_replace_to "creatures", target: "creature_#{id}"
broadcast_replace_to "creatures_main", target: "creature_main_#{id}"
}
after_destroy_commit {
broadcast_remove_to "creatures"
broadcast_remove_to "creatures_main"
}
<%= turbo_frame_tag "creature_#{creature.id}" do %>
<%= link_to creature.name, "#" %>
<% end %>
<%= turbo_frame_tag "creature_main_#{creature.id}" do %>
<%= link_to creature.name, "#" %>
<% end %>
Конечно, это означает, что вам, возможно, придется использовать 2 разных партиала, если у вас есть
turbo_frame_tag
внутри частичного. Сделать это можно так:
after_update_commit {
# target here is the ID of each of the creature div
broadcast_replace_to "creatures", target: "creature_#{id}", partial: "creatures/creature", locals: {creature: self}
broadcast_replace_to "creatures_main", target: "creature_main_#{id}", partial: "creatures/creature_main", locals: {creature: self}
}
Кстати, вы должны использовать _ более позднюю версию этих методов. Также используйте коллекцию рендеров для облегчения чтения.