【问题标题】:Rails 5 ReferenceError: function is not definedRails 5 ReferenceError:未定义函数
【发布时间】:2017-07-14 00:05:46
【问题描述】:

我正在尝试(现在整个上午:-S)在 onChange 上加载一个 js 函数来填写表单中的一些字段。 我已经为此搜索了解决方案,这让我添加了 jquery-turbolinks,甚至尝试删除了 turbolinks。这不起作用。

为什么无法识别功能?

ReferenceError: update_sub_process_fields 未定义

应用程序.js

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require bootstrap-datepicker/core
//= require bootstrap-datepicker/locales/bootstrap-datepicker.pt.js
//= require_tree .

sub_processes.coffee

ready = ->

update_sub_process_fields = (sub_process_type_id) ->
  jQuery.ajax
    url: '/sub_processes/update_fields'
    type: 'GET'
    data: 'sub_process_type_id': sub_process_type_id
    dataType: 'html'
    success: (data) ->
      jQuery('#sub_process_fields').html data
      return
  return

$(document).ready(ready)
$(document).on('page:load', ready)

_form.erb.html

 <div class="field">
   <%= f.label :sub_process_type %>
   <%= f.select(:sub_process_type_id, options_for_select(SubProcessType.all.map {|s| [s.name, s.id]},sub_process.sub_process_type_id),{prompt: "Select Sub Process...", include_blank:true}, onChange: "update_sub_process_fields(this.value)") %>
  </div>


  <div class="field">
    <%= f.label :codenr %>
    <%= f.text_field :codenr %>
  </div>

<div id = "sub_process_fields">
  <div class="field">
    <%= f.label :name %>
    <%= f.text_field :name %>
  </div>

  <div class="field">
    <%= f.label :description %>
    <%= f.text_field :description %>
  </div>
</div>

【问题讨论】:

  • 1.您的咖啡脚本样本中的缩进是否正确?我认为update_sub_process_fields 应该缩进到您的准备函数中? 2. 尝试使用window.update_sub_process_fields = ... 而不是update_sub_process_fields = ...。如果可行,我会添加一个答案来解释原因
  • 非常感谢,添加window. 已修复。缩进没有做任何事情(除了增加可读性)。请解释一下。
  • " 缩进没有做任何事情(除了增加可读性)" 是不对的,缩进定义了 CoffeeScript 的结构。您的问题是一个空的 ready 函数。
  • @muistooshort,在这个特定的场景中,添加窗口并保持原来的缩进也是可行的。
  • @MrWater,实际上@muistooshort 是对的。您为准备就绪而编译的 JS 如下所示:ready = function() {};,这意味着 window.update_sub_process_fields 在您的准备就绪事件之前定义 - 这很好,因为它不需要 jQUery 或 DOM,直到它通过事件触发。但我认为它应该在您的 ready 函数中,否则 ready 和 $(document)... 语句什么都不做。

标签: jquery ruby-on-rails ajax coffeescript


【解决方案1】:

解决方案

根据我的评论,您需要通过全局 window 对象公开您的函数。

所以替换:

update_sub_process_fields = (sub_process_type_id) ->

与:

window.update_sub_process_fields = (sub_process_type_id) ->

说明

Coffeescript 不会使局部变量全局可访问。在 JS 中你可以这样写:

var a = 1;
b = 2;

这里的a 是当前上下文的局部变量,而b 是一个全局变量。

由于 Coffeescript 中没有 var 关键字,它使每个变量都成为局部变量(以避免污染全局命名空间并导致错误)。要公开它,您需要使用像 commonjs 这样的系统来跨文件导入/导出或,您可以将其附加到全局对象。在浏览器中是 window,而在服务器端 nodejs 应用程序中是 global。

您可以通过在您的咖啡脚本中通过delegated listener 附加onChange 事件来绕过它。

例如:

document.on 'change', '.sub_process_type', update_sub_process_fields

其中.sub_process_type 是选择框上您要监听更改的类。


编辑

要通过事件侦听器获取值,您必须使用 event 对象 which is passed to event listeners by default。

update_sub_process_fields = (event) ->
  sub_process_type_id = event.target.value
  jQuery.ajax
    url: '/sub_processes/update_fields'
    type: 'GET'
    data: 
      sub_process_type_id: sub_process_type_id
    dataType: 'html'
    success: (data) ->
      jQuery('#sub_process_fields').html data
      return
  return

【讨论】:

  • 使用 document.on 'change', '.sub_process_type', update_sub_process_fields 不会让我获得当前选择的值,还是会?
  • @MrWater 请参阅上面的编辑。您将需要从包含对选择元素的引用的事件对象中获取所选值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 2019-04-26
相关资源
最近更新 更多