首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ajax的Select2被多次使用Rails turbolinks事件初始化。

使用ajax的Select2被多次使用Rails turbolinks事件初始化。
EN

Stack Overflow用户
提问于 2016-04-08 10:46:46
回答 6查看 5.9K关注 0票数 23

我是一个使用Rails 4.2.6开发Rails应用程序的人。我使用Turbolinks与jquery.turbolinks (对不起,我不能张贴到这些元素的链接,因为我是一个新手在网站上)。我的问题很简单,但我就是解决不了。如下所示:我有一个通过AJAX获取的表单

代码语言:javascript
复制
<div class="card-footer">
  <a class="btn btn-sm btn-primary-outline" data-remote="true"  href="/profiles/Mke5kA/positions/new"><i class="fa fa-plus"></i> Nouvelle expérience professionnelle</a>
  <div id="new_position_form"></div>
</div>

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

代码语言:javascript
复制
= simple_form_for [profile, position], remote: true, html: {id: 'positionForm', class: 'm-b-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'
  • Select2元素目前在Rails Trubolinks事件“页面:加载页:更新”上被“激活”,但我也尝试过“页面:更改”。
  • 获取表单时: select2元素很好(正确激活):

当我尝试输入使用AJAX获取数据的Select2时,就会出现问题:所有的select2s都是复制的:

下面是如何初始化Select2:

代码语言:javascript
复制
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($('<option selected></option>').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”)对取消Select2 ( Select2 2-隐藏可访问的类Select2添加到初始化的Select2元素)的元素,但它不起作用。

非常感谢您的友好帮助!

EN

回答 6

Stack Overflow用户

发布于 2017-01-28 21:39:56

当使用Turbolinks 5和select2时,当使用back按钮返回页面时,不再将select2对象附加到<select> (请参见下面的测试)。返回后会创建并附加一个新的select2对象,但它是不可用的。

杰克的回答对我没有用,因为当添加新的select2对象时,<select>仍然有设置width: 1px !important<select>。创建新的select2对象时,它基本上是不可见的。

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

代码语言:javascript
复制
$(document).on("turbolinks:before-cache", function() {
  $('.select2-input').select2('destroy');
});

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

更详细

我相信这是正确的方法,鉴于Turbolinks文档 (强调地雷):

准备要缓存的页面 如果您需要在Turbolinks缓存文档之前准备文档,请侦听图文链接:缓存前事件。您可以使用此事件重置表单、折叠扩展的UI元素、或删除任何第三方小部件,这样页面就可以再次显示。

测试select2存在性

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

代码语言:javascript
复制
('.select2-input').first().data('select2')
票数 42
EN

Stack Overflow用户

发布于 2016-08-26 18:16:33

2021更新

使用turbolinks:before-cache

代码语言:javascript
复制
document.addEventListener('turbolinks:before-cache', function () {
  // removing the select2 from all selects
  $("select").select2('destroy');
});

并在select2时加载turbolinks:load

代码语言:javascript
复制
document.addEventListener("turbolinks:load", function () {
  // applying select2 to all selects
  $("select").select2({
    theme: 'bootstrap4' // if you want to pass some custom config
  });
});

当然,您可以创建一个自定义的.select2-binder类或一个data-select2-binder来选择哪个选择会受到影响。

我也有同样的问题,我通过这样做来解决:

代码语言:javascript
复制
// init.js (you can pass an container instead of using document

$( document ).on('turbolinks:load', function() {
  $( document ).find('select').not('.select2-hidden-accessible').select2();
});

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

票数 5
EN

Stack Overflow用户

发布于 2016-11-23 15:18:37

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

下面是初始化select2之前所做的工作:

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

代码语言:javascript
复制
if ($(el).data('select2') == undefined && $(el).next().hasClass('select2-container')) {
  $(el).next().remove();
}
$(el).select2();
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36497723

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档