仅前端更改
为了使用仅前端选项,我建议以下内容。
- 我们需要为该可折叠元素存储状态。
- 我们需要在每次套接字通道更新时恢复该元素的可折叠状态
为简单起见,我将使用纯 JavaScript。
我们需要修改按钮,并编写函数来存储状态(我使用简单的localStorage)
<a class="collapse_trigger" onclick="memoizeCollapsibleState()">...</a>
<script type="text/javascript">
function memoizeCollapsibleState() {
if (!localStorage.getItem('collapsibleState')) {
localStorage.setItem('collapsibleState', true)
} else {
localStorage.removeItem('collapsibleState')
}
}
</script>
之后我们需要编写函数来从本地存储中恢复该状态
function restoreCollapsibleState() {
var collapsibleEl = document.getElementById('collapseExample');
if (localStorage.getItem('collapsibleState')) {
collapsibleEl.classList.add('is-active')
}
}
最后一刻我们需要将该函数绑定到phoenix_live_view
套接字更新,我们需要在加载窗口后立即执行此操作。
window.onload = init;
function init() {
liveSocket.getSocket().channels[0].onMessage = function (e, t, n) {
setTimeout(restoreCollapsibleState, 10)
return t
}
}
函数的目的setTimeout
是套接字更新是异步操作,我们需要添加一些延迟才能恢复可折叠状态。10ms 似乎没问题,但我们可以将其更改为任何其他去抖动功能,我只是为了简单起见,认为这是概念证明
仅后端更改
我刚刚用默认的 live phoenix 结构做了一个例子
mix phx.new my_app --live
为其添加了引导程序(但我认为 bulma 遵循大致相同的规则)并将 phoenix 实时模板修改为以下
<div class="collapse <%= if (@results && String.trim(@query) != ""), do: "show", else: "" %>" id="collapseExample">
<div class="card card-body">
<%= for {app, _vsn} <- @results do %>
<p value="<%= app %>"><%= app %></p>
<% end %>
</div>
</div>
因此,如果有任何结果并且查询不为空,则永远不会折叠。
对于你的情况,我认为它会略有不同
<a class="collapse_trigger">...</a>
<div class="is-collapsible <% if (@results && String.trim(@query) != "") do: "is-active", else: "" %>">
# content
</div>