带有ajax的Select2使用Rails turbolinks事件多次初始化

我正在使用Rails 4.2.6开发Ruby On Rails应用程序。 我正在使用Turbolinks和jquery.turbolinks(抱歉,我不能发布这些元素的链接,因为我是网站上的新手)。 我的问题很简单,但我无法解决。 这是:我有一个通过AJAX获取的表单

 

表单包含通过AJAX获取数据的Select2元素

 = simple_form_for [profile, position], remote: true, html: {id: 'positionForm', class: 'mb-1'} do |f| = f.input :company_id, as: :select, input_html: {:'data-behaviour' => 'company-select2', :'data-kind' => 'company'} = f.input :title = f.input :summary - location = f.object.build_location = f.simple_fields_for :location do |l| = render 'locations/fields', l: l, city: position.city = render "profiles/shared/date_fields", f: f, model: position = f.input :skill_list, as: :select, input_html: {multiple: true, :data => {:behaviour => 'acts-as-taggable', :'taggable-context' => 'skills'}} %button.btn.btn-primary{:type => "submit"}= icon('check-square-o', 'Enregistrer') = link_to icon('remove', 'Annuler'), 'javascript:void(0)', data: {:'lgnk-behaviour' => "remove-form", :'lgnk-target' => "#positionForm" }, class: 'btn btn-secondary' 
  • 当Rails Trubolinks事件“页面:加载页面:更新”时,Select2元素被“激活”,但我也尝试过“页面:更改”
  • 获取表单时:select2元素很好(正确激活):

初始形式(在AJAX获取之后

当我尝试在使用AJAX获取数据的Select2中输入时出现我的问题:所有select2都是重复的:

在此处输入图像描述

这是我如何初始化Select2:

 var loc_tag = function() { $('[data-behaviour="acts-as-taggable"]').not('.select2-hidden-accessible').each (function (index, element) { if ($(element).data('value')) { var options = $(element).data('value').split(', '); $.each(options, function(key, tag){ $(element).append($('').val(tag).text(tag)); }); } $(element).select2({ ajax: { url: "/tags?context="+$(element).data('taggable-context'), dataType: 'json', headers: { "Accept": "application/json" }, delay: 250, data: function (params) { return { q: params.term, // search term page: params.page }; }, processResults: function (data, page) { return { results: data }; }, cache: true }, escapeMarkup: function (markup) { return markup; }, // let our custom formatter work minimumInputLength: 2, tags: true, language: "fr", theme: "bootstrap", width: "100%", placeholder: 'Mots clés...' }); }); }; $(document).on('page:load page:update', loc_tag); 

我希望Select2元素只被初始化一次(当获取表单时)而不是AJAX响应它们获取它们的数据。 我已经尝试了jQuery.not(“。select2-hiden-accessible”)对未使用Select2的元素(select2-hidden-accessible是类Select2添加到初始化的Select2元素)但它不起作用。

非常感谢您的帮助!

使用Turbolinks 5和select2时,使用后退按钮返回页面时,不再将select2对象附加到 (参见下面的测试)。 返回后创建并附加一个新的select2对象,但它无法使用。

jack的回答对我不起作用,因为当添加新的select2对象时, 仍然有class='select2-hidden-accessible' ,除其他外,它设置width: 1px !important 。 当创建新的select2对象时,它基本上是不可见的。

对我来说,关键是在TL缓存页面之前销毁所有select2对象 。 这是适合我的解决方案:

 $(document).on("turbolinks:before-cache", function() { $('.select2-input').select2('destroy'); }); $(document).on('turbolinks:load', function() { $('.select2-input').select2(); }); 

更多详情

我相信这是Turbolinks文档 (强调我的)的正确方法:

准备要缓存的页面

如果您需要在Turbolinks缓存之前准备文档,请收听turbolinks:before-cache事件。 您可以使用此事件重置表单,折叠展开的UI元素或拆除任何第三方窗口小部件,以便页面可以再次显示。

测试select2

要测试select2对象是否附加到您可以在控制台中执行以下操作:

 ('.select2-input').first().data('select2') 

我有同样的问题,我发现当你按下后退按钮时, selectselect2元素都被渲染,但它们没有被绑定在一起所以当你用$('select).select2()重新初始化时,它会创建另一个旁边是全新的select2元素。

所以这是我在初始化select2之前所做的:

如果select不是select2 (即$(el).data('select2') == undefined )但是旁边已经有一个select2元素,则将其删除。

 if ($(el).data('select2') == undefined && $(el).next().hasClass('select2-container')) { $(el).next().remove(); } $(el).select2(); 

我遇到了同样的问题,我通过这样做解决了:

 // init.js (you can pass an container instead of using document $( document ).on('turbolinks:load', function() { $( document ).find('select').not('.select2-hidden-accessible').select2(); }); 

现在我没有那些重复的选择:)

这里没有什么对我有用。

通过不使用select缓存页面,我完全可以解决这个问题。

我在页面顶部使用选项: <% provide(:no_cache, true) %>

我在application.html.erb上使用它:

 <% if yield(:no_cache) %>  <% end %>