rails jquery.turbolinks javascript在页面更改后未触发

Posted

技术标签:

【中文标题】rails jquery.turbolinks javascript在页面更改后未触发【英文标题】:rails jquery.turbolinks javascript not firing after page change 【发布时间】:2014-11-04 04:50:03 【问题描述】:

意识到这个问题(或类似问题)已经被广泛记录,但尽管我进行了调查和阅读,但我仍然无法解决这个问题,因为......

安装了以下 gem 的 Rails 4 应用程序:

Using rake 10.3.2
Using i18n 0.6.11
Using json 1.8.1
Using minitest 5.4.1
Using thread_safe 0.3.4
Using tzinfo 1.2.2
Using activesupport 4.1.4
Using builder 3.2.2
Using erubis 2.7.0
Using actionview 4.1.4
Using rack 1.5.2
Using rack-test 0.6.2
Using actionpack 4.1.4
Using mime-types 1.25.1
Using polyglot 0.3.5
Using treetop 1.4.15
Using mail 2.5.4
Using actionmailer 4.1.4
Using activemodel 4.1.4
Using arel 5.0.1.20140414130214
Using activerecord 4.1.4
Using execjs 2.2.1
Using autoprefixer-rails 3.0.1.20140826
Using bcrypt 3.1.7
Using sass 3.2.19
Using bootstrap-sass 3.2.0.2
Using bootstrap-select-rails 1.6.2
Using thor 0.19.1
Using railties 4.1.4
Using bootswatch-rails 3.2.4
Using breadcrumbs_on_rails 2.3.0
Using cancan 1.6.10
Using coffee-script-source 1.8.0
Using coffee-script 2.3.0
Using coffee-rails 4.0.1
Using data-confirm-modal 1.0.1 from git://github.com/ifad/data-confirm-modal.git (at master)
Using datetimepicker-rails 3.1.1 from git://github.com/zpaulovics/datetimepicker-rails.git (at master)
Using orm_adapter 0.5.0
Using warden 1.2.3
Using devise 3.3.0
Using hike 1.2.3
Using multi_json 1.10.1
Using tilt 1.4.1
Using sprockets 2.11.0
Using intellij-coffee-script-debugger 0.0.1 from git://github.com/JetBrains/intellij-coffee-script-debugger.git (at master)
Using jbuilder 2.1.3
Using jquery-rails 3.1.2
Using sprockets-rails 2.1.4
Using sass-rails 4.0.3
Using jquery-datatables-rails 2.2.3
Using turbolinks 2.3.0
Using jquery-turbolinks 2.1.0
Using momentjs-rails 2.7.0
Using nested_form 0.3.2
Using pg 0.17.1
Using bundler 1.6.4
Using rails 4.1.4
Using rdoc 4.1.1
Using sdoc 0.4.1
Using simple_form 3.1.0.rc2
Using spring 1.1.3
Using sqlite3 1.3.9
Using uglifier 2.5.3
Using will_paginate 3.0.7

我的 application.js 清单如下:

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require_self
//= require_tree .
//= require bootstrap-sprockets
//= require data-confirm-modal
//= require allPages
//= require moment
//= require bootstrap-datetimepicker
//= require pickers
//= require locales/bootstrap-datetimepicker.hu
//= require dataTables/jquery.dataTables
//= require dataTables/bootstrap/3/jquery.dataTables.bootstrap
//= require jquery_nested_form
//= require bootstrap-select
//= require bootstrap/alert
//= require bootstrap/dropdown
//= require turbolinks

我有一个带有以下 _form.html.erb 部分的客户模型:

<%= simple_form_for(@customer, html:  class: 'form-horizontal' ,
  wrapper: :horizontal_form,
  wrapper_mappings: 
    check_boxes: :horizontal_radio_and_checkboxes,
    radio_buttons: :horizontal_radio_and_checkboxes,
    file: :horizontal_file_input,
    boolean: :horizontal_boolean
 ) do |f| %>
<%= f.error_notification %>
<fieldset>
  <div class="form-inputs">
    <%= f.input :code, required: true %>
    <%= f.input :name, required: true %>
    <%= f.input :location, required: true, 
                    :collection => LookupValue.joins(:lookup).where(lookups:  :name => 'Location' ).order(name: :asc).pluck(:name), 
                    :include_blank => false, 
                    input_html:  class: 'selectpicker'  %>
        <%= f.input :service_level, 
                    :collection => LookupValue.joins(:lookup).where(lookups:  :name => 'Service level' ).order(name: :asc).pluck(:name), 
                    :include_blank => false,
                    input_html:  class: 'selectpicker'  %>
        <%= f.input :golive_date, :as => :date_picker %>
        <%= f.input :connection_type, 
                    :collection => LookupValue.joins(:lookup).where(lookups:  :name => 'Connection type' ).order(name: :asc).pluck(:name), 
                    :include_blank => false,
                    input_html:  class: 'selectpicker'  %>
        <%= f.input :service_centre, 
                    :collection => LookupValue.joins(:lookup).where(lookups:  :name => 'Service centre' ).order(name: :asc).pluck(:name), 
                    :include_blank => false,
                    input_html:  class: 'selectpicker'  %>
        <%= f.input :end_date, :as => :date_picker %>
        <%= f.input :sla, 
                    :collection => LookupValue.joins(:lookup).where(lookups:  :name => 'SLA' ).order(name: :asc).pluck(:name), 
                    :include_blank => false,
                    input_html:  class: 'selectpicker'  %>
        <%= f.input :project_code %>
      </div>

  <div class="form-actions">
     <%= f.button :submit, :class => "btn btn-primary" %>
  </div>
</fieldset>
<% end %>

我的 customer.js.coffee 脚本文件是:

# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

jQuery ->
  $('#customers').dataTable
    sPaginationType: "full_numbers"
    bProcessing: true
    bServerSide: true
    sAjaxSource: $('#customers').data('source')
    iDisplayLength: 200
    oLanguage:
      sLengthMenu: "Display <select>" + "<option value=\"50\">50</option>" + "<option value=\"100\">100</option>" + "<option value=\"300\">300</option>" + "<option value=\"-1\">All</option>" + "</select> records"

  $(".selectpicker").selectpicker

当我直接加载客户编辑页面或使用浏览器刷新按钮刷新页面时,分配有“selectpicker”类的字段会拾取 bootstrap-select-rails gem 格式的选择字段并应用更新后的外观和bootstrap-select-rails select 的感觉(这是正确的行为)。但是,如果我在客户模型页面中的任何位置选择一个 rails 链接,然后返回到客户编辑页面,则表单呈现时没有来自 bootstrap-select-rails gem 的增强选择字段,而是显示正常的默认引导选择字段。

如果我再次使用浏览器按钮重新加载页面,则会正确加载增强的选择字段。

问题是我安装了 turbolinks 和 jQuery.turbolinks 并且 application.js 清单文件以正确的顺序加载了所有正确的引用我很困惑为什么 jquery.turbolinks 不处理 javascript 的加载页面加载和页面都会自动更改?它似乎只适用于初始页面加载(或浏览器刷新),并且任何 rails 页面更改都不会重新加载 javascript。

【问题讨论】:

【参考方案1】:

我不知道您是否找到了解决问题的方法。我在我目前正在处理的项目中遇到了同样的问题,我发现在我的 javascript 控制器文件中添加这段代码似乎可以解决问题:

$(document).on('page:load', function()
    $('.selectpicker').selectpicker();
);

【讨论】:

【参考方案2】:

这解决了我的问题:

$(document).on('page:load', function()
  $('.selectpicker').selectpicker('render');
);

参考:Bootstrap-Select

【讨论】:

【参考方案3】:

可能你正在用咖啡来写你的脚本,所以你可以这样写:

(($) ->
  $(document).on 'page:change', ->
    $('.dropdown-toggle').dropdown()
    $('.selectpicker').selectpicker()
) jQuery

【讨论】:

【参考方案4】:

另一种方法可能是:

$('.selectpicker').selectpicker('refresh');

来自文档:

要使用 JavaScript 以编程方式更新 select,首先操作 select,然后使用 refresh 方法更新 UI 以匹配新状态。在删除或添加选项,或通过 JavaScript 禁用/启用 select 时,这是必需的。

【讨论】:

以上是关于rails jquery.turbolinks javascript在页面更改后未触发的主要内容,如果未能解决你的问题,请参考以下文章

使用 ajax 的 Select2 被 Rails turbolinks 事件初始化了几次

可以在 Rails 中创建此重定向路线吗?

jquery-ui-rails 打破 rails 测试

由于rails资产,jQuery事件多次触发?

rails.vim环境安装(ubuntu)

Rails 4 - 只响应 JSON 而不是 HTML