代码之家  ›  专栏  ›  技术社区  ›  user3574603

rails 5:为什么在用变量设置部分id的输入时会得到500个响应,而在使用字符串文本时却没有?

  •  0
  • user3574603  · 技术社区  · 6 年前

    我有一个表格,我已经提取了一部分。

    <%= form_with url: filtered_tags_path, class: 'filter-box' do %>
      <%= text_field_tag(:filter_by, '', id: 'filter-text-field', autocomplete: 'off') %>
    <% end %>
    <script>watch_form()</script>
    

    里面有个剧本 application.js 它监视文本字段中的更改,并在每次按键后触发请求:

    function watch_form() {
      document.getElementById('filter-text-field').addEventListener('keyup', function(){
        Rails.fire(this.form, 'submit')
      })
    }
    

    相应的操作如下所示:

    def create
      @labels = Label.by_search_term(params[:filter_by])
      respond_to do |format|
        format.js
      end
    end
    

    使用此模板:

    document.querySelector('.filter-results')
            .innerHTML = "<%= escape_javascript(render partial: 'filtered_results') %>"
    

    使:

    <% if @labels.present? %>
      <% @labels.each do |label| %>
        <%= label_link(name: label.name, is_remote: true) %>
      <% end %>
    <% else %>
      <div class="badge no-tags-badge">No tags found</div>
    <% end %>
    

    简而言之,将呈现一系列按钮(包装在表单中)。例如:

    <form class="button_to" method="post" action="/issues?labels%5B%5D=ready" data-remote="true">
      <input class="label-badge" type="submit" value="+ ready">
      <input type="hidden" name="authenticity_token" value="yvWh51r/xHqLPb5V/qdfeiar/j9fqd/8FoZM0jnRFUFEHkdU5WlgVjyaIQi9viiiSfckjJypOhMnKAh29wjY3w==">
    </form>
    

    当我点击一个按钮时,它发送它的请求,我得到一个成功的响应。

    我想要两份分开的表格。我的第一步是交换 id 变量的窗体文本字段。

    <%= form_with url: filtered_tags_path, class: 'filter-box' do %>
      <%= text_field_tag(:filter_by, '', id: filter_field_id, autocomplete: 'off') %>
    <% end %>
    <script>watch_form()</script>
    

    像这样把它传递给部分:

    <div class="filter-form">
      <%= render partial: 'filter_form', locals: { filter_field_id: 'filter-text-field' } %>
    </div>
    

    表单的行为与以前完全一样。每个按键都会呈现按钮。除了真实性令牌之外,示例按钮看起来完全相同。

    <form class="button_to" method="post" action="/issues?labels%5B%5D=ready" data-remote="true">
      <input class="label-badge" type="submit" value="+ ready">
      <input type="hidden" name="authenticity_token" value="0xjeK53JZSF0nSA2kUT2MREgaCeQ8RlmK2wqcd2sCIZd8ziYIl/BDcM6v2vSXYHpfnyylFPx/Ikawm7VE3XFGA==">
    </form>
    

    没什么能说明有什么不同,但这次,只要点击一个按钮,我就会得到一个 500 反应。

    在控制台中,我看到:

    rails-ujs.self-d109d8c5c0194c8ad60b8838b2661c5596b5c955987f7cd4045eb2fb90ca5343.js?body=1:212
    
    POST http://localhost:3000/issues?labels%5B%5D=documentation&labels%5B%5D=ready 500 (Internal Server Error)
    
    Rails.ajax  @ rails-ujs.self-d109d…a5343.js?body=1:212
    Rails.handleRemote  @ rails-ujs.self-d109d…a5343.js?body=1:568
    (anonymous) @ rails-ujs.self-d109d…a5343.js?body=1:169
    

    现在,我完全迷路了。我试过将javascript绑定到 turbolinks:load 事件侦听器,但这并没有产生什么影响。

    我唯一能想到的是这和真品有关。

    将字符串文本作为id传递和使用变量有什么区别?为什么我的零钱会打破一切?我需要做什么才能成功?

    更新

    我发现单击页面上的任何类似按钮,除了在输入更改时呈现的按钮外,还将导致 五百 反应。

    更新2

    Rails控制台中的错误:

    ActionView::Template::Error (undefined local variable or method `filter_field_id' for #<#<Class:0x00007fa891909b60>:0x00007fa88bf7ef78>
    Did you mean?  file_field):
        1: <%= form_with url: filtered_tags_path, class: 'filter-box' do %>
        2:   <%= text_field_tag(:filter_by, '', id: filter_field_id, autocomplete: 'off') %>
        3: <% end %>
        4: <script>watch_form()</script>
    
    app/views/issues/_filter_form.html.erb:2:in `block in _app_views_issues__filter_form_html_erb___4066184210884757332_70181011505480'
    app/views/issues/_filter_form.html.erb:1:in `_app_views_issues__filter_form_html_erb___4066184210884757332_70181011505480'
    app/views/issues/create.js.erb:14:in `_app_views_issues_create_js_erb__4388147431667736133_70180939735900'
    

    从中可以看出,当我在 create.js.erb . 所以我修改为:

    document.querySelector('.filter-form')
            .innerHTML = "<%= escape_javascript(render 'filter_form', locals: { :filter_field_id=> 'filter-text-field' }) %>"
    

    但我还是犯了同样的错误。 undefined local variable or method 'filter_field_id'

    0 回复  |  直到 6 年前
        1
  •  1
  •   Eugene Demidov    6 年前

    如果不使用 partial . 你不需要 locals 在你 create.js.erb file .

    见: https://api.rubyonrails.org/classes/ActionView/PartialRenderer.html#class-ActionView::PartialRenderer-label-Rendering+the+default+case

    # Instead of <%= render partial: "account", locals: { account: @buyer } %>
    <%= render "account", account: @buyer %>
    

    所以你的代码应该是:

    document.querySelector('.filter-form')
            .innerHTML = "<%= escape_javascript(render 'filter_form', filter_field_id: 'filter-text-field' ) %>"
    

    document.querySelector('.filter-form')
            .innerHTML = "<%= escape_javascript(render partial: 'filter_form', locals: { filter_field_id: 'filter-text-field' }) %>"
    
    推荐文章