Rails 7 JavaScript事件听众在浏览器返回后停止工作吗?
我有Rails 7应用程序,我正在尝试使用 tom-select 或纤细 - 选择。无论我使用哪个库,我的问题都会重现,因此,这一定是我的铁路方面的问题。
app/views/cities/index.html.erb
<%= form_for :city, url: cities_path, method: 'GET' do |f| %>
<div class="mt-4 border bg-light px-4 py-3 rounded-3">
<%= f.select :search_city, [], {},
placeholder: 'Type to search',
data: {
controller: 'ts--search',
ts__search_url_value: autocomplete_cities_path
} %>
<%= f.submit 'Search', class: 'btn mx-auto' %>
</div>
<% end %>
,这是我的JS控制器(在这种情况下,我正在使用tom-select) app/javascript/controllers/ts/search_controller.js
import { Controller } from "@hotwired/stimulus";
import { get } from "@rails/request.js";
import TomSelect from "tom-select";
export default class extends Controller {
static values = { url: String };
connect() {
var config = {
plugins: ["input_autogrow", "remove_button", "no_active_items"],
render: {
option: this.render_option,
item: this.render_option,
},
valueField: "value",
loadThrottle: 400,
load: (q, callback) => this.search(q, callback),
closeAfterSelect: true,
persist: false,
create: false,
delimiter: ", ",
maxItems: 10,
};
new TomSelect(this.element, config);
}
async search(q, callback) {
const response = await get(this.urlValue, {
query: { query: q },
responseKind: "json",
});
if (response.ok) {
callback(await response.json);
} else {
console.log("Error in search_ctrl: ");
callback();
}
}
render_option(data, escape) {
return `<div>${escape(data.text)}</div>`;
}
}
app/controllers/controllers/cotities_controller.rb
class CitiesController < ApplicationController
def index
end
def autocomplete
list = City.order(:name)
.where("name ilike :q", q: "%#{params[:q]}%")
render json: list.map { |u| { text: u.name, value: u.id, sub: u.state } }
end
end
问题repro repro :
- 开放城市索引并单击搜索酒吧。
- 下拉列表打开,我可以输入并选择一个建议。一旦选择,建议在搜索栏中出现“ x”单击的搜索栏,该建议将从搜索栏中删除它。
- 我添加任何数量的搜索令牌,1-N。
- 单击“搜索” - &GT;查看结果页面。
- 单击浏览器中的备用按钮(或在手机上滑动)
预期行为: 搜索栏与搜索之前完全一样。单击“ X”删除令牌。单击搜索栏允许输入搜索查询并添加更多令牌。
实际行为: 我可以看到令牌,但是除了“搜索”按钮之外,请单击其他任何内容,什么也不做。 我可以看到多个演示中的相同行为,例如一个 href =“ https://coolrequest.dev/2021/11/25/replace_select2.html” rel =“ nofollow noreferrer”>一个。
回来后如何使JS工作?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当使用浏览器“返回按钮”时访问并显示页面的缓存副本。在访问另一个页面之前,该副本就保存了。任何附带的JavaScript行为都会丢失,我们只会得到HTML。
当刺激连接到 [data-controller = ts-search] select 元素由 tomSelect 从这样
做:
当单击另一个链接时,此修改后的HTML保存到缓存中,然后在使用浏览器后退导航时恢复后来还原。然后,刺激再次连接,但是, tomSelect skips
.tomselected
元素,以避免再次附加 .ts-wrapper 。它看起来相同,因为HTML和样式已加载,但没有附加JavaScript行为。我们可以通过打开 impoulus 调试记录来获得更多上下文:
如果带有搜索表格的页面被缓存,并且我们通过单击链接来导航到它:
使用浏览器后返回导航时:
还有一件事发生。从我们的表单中导航时(通过单击“浏览器”或“向前浏览器”向前):
在该页面被 turbo , signulus 调用
disconnect()在我们的搜索控制器中。我们可以在此处重新恢复原始选择,然后在涡轮增压之前。这样,可以在缓存的页面上重新应用TomSelect TomSelect 。
https://turbo.hotwired.dev/
https://turbo.hotbo.hotwired.dev /手册/建筑物#理解-Caching
https://tom-select.js.org/docs/api/#destroy
When browser "back button" is used Turbo Drive does a restoration visit and displays a cached copy of the page. This copy is saved just before visiting another page. Any attached javascript behavior is lost, we only get html.
When Stimulus connects to [data-controller=ts--search] the select element is modified by TomSelect from this:
to this:
When clicking another link, this modified html is saved to cache and later is restored when using browser back navigation. Then Stimulus connects again, however, TomSelect skips
.tomselected
elements to avoid appending .ts-wrapper again. It looks the same because html and styles are loaded, but no javascript behavior is attached.We can get a bit more context by turning on Stimulus debug logging:
If the page with the search form is cached and we navigate to it by clicking a link:
When using browser back navigation:
One more thing happens when navigating away from our form (by clicking away, browser back or browser forward):
Before the page is cached by Turbo, Stimulus calls
disconnect()
in our search controller. We can restore the original select here, before turbo caches the page. This way TomSelect can be reapplied on the cached page.https://turbo.hotwired.dev/handbook/drive#restoration-visits
https://turbo.hotwired.dev/handbook/building#understanding-caching
https://stimulus.hotwired.dev/reference/lifecycle-callbacks#disconnection
https://tom-select.js.org/docs/api/#destroy