【问题标题】:Updating instance variables through AJAX call in Rails to display in form在 Rails 中通过 AJAX 调用更新实例变量以在表单中显示
【发布时间】:2019-02-01 09:16:03
【问题描述】:

这是我想要做的:

  1. 用户粘贴 URL。
  2. 用户粘贴的输入框有一个触发urlPasted()函数的:onpaste。
  3. urlPasted() 函数提交输入框所在的表单,该表单对名为lookup_profile 的自定义函数进行AJAX 调用。
  4. 在控制器中,lookup_profile 函数执行一些网络请求,然后更新一些实例变量。
  5. 一旦这些变量被更新(大约需要 5 秒),视图就会有一个等待 20 秒的函数,并使用这些实例变量的结果更新模态框上的文本框。

这是我目前的观点:

  <%= form_tag url_for(:controller => 'users', :action => 'lookup_profile'), id: "profileLookupForm", :method => 'post', :remote => true, :authenticity_token => true do  %>
      <div class="form-group row">
        <div class="col-sm-12">
          <%= text_field_tag "paste_data", nil, onpaste: "profileURLPasted();", class: "form-control"%>
        </div>
      </div>
  <% end %>

  <script type="text/javascript">
      function profileURLPasted() {
        // Once the user pastes data, this is going to submit a POST request to the controller.
        setTimeout(function () { 
            document.getElementById("profileLookupForm").submit();
        }, 100);
        setTimeout(function () { 
            prefillForm();
        }, 20000);
      };

    function prefillForm() {
    // Replace company details.
    $('#companyNameTextBox').val("<%= @company_name %>");
  };
  </script>

这是控制器的外观:

  def lookup_profile
    # bunch of code here
    @company_name = "Random"
  end

现在这是我遇到的问题。当用户粘贴数据时,它完美地提交到 custom_action lookupProfile。然而,在lookupProfile 运行它的代码之后,rails 不知道接下来要做什么。我的意思是它给了我这个错误:

Users#lookup_profile 缺少此请求格式的模板,并且 变体。 request.formats: ["text/html"] request.variant: []

事实上,我实际上在views/users/lookup_profile.js.erb 有一个文件。出于某种原因,它试图呈现 HTML 版本。我不知道为什么。

其次,我尝试将其放入控制器中:

    respond_to do |format|  
        format.js { render 'users/lookup_profile'}
    end

但这会导致此错误:

ActionController::UnknownFormat

任何帮助将不胜感激。我只想让自定义函数运行,更新实例变量,然后让我用该数据更新当前表单。

这是我正在尝试做的类似事情的另一个 stackoverflow 参考:Rails submitting a form through ajax and updating the view 但此方法不起作用(出现 actioncontroller 错误)

* 编辑 1 *

好的,所以我通过将 form_tag 替换为以下内容来修复 ActionController 错误:

<%= form_tag(lookup_profile_users_path(format: :js), method: :post, :authenticity_token => true, id: 'profileLookupForm', remote: true) do %>

但现在它实际上将实际的 javascript 渲染到视图中,我不希望这样。我只是希望能够访问在 lookup_profile 操作中更新的实例变量,而不是显示视图。

* 编辑 2 *

所以我认为我的问题归结为:在表单中放置一个按钮并从 IT 提交与我提交表单的 javascript 代码不同。如果我能弄清楚这是怎么回事,那么我想我的状态可能很好。

【问题讨论】:

    标签: javascript ruby-on-rails ajax


    【解决方案1】:

    你在那里混合了一些东西。首先,而不是做document.getElementById("profileLookupForm").submit() 你应该做一个ajax 请求,我猜submit() 方法忽略了来自rails 的remote: true 指令。

    所以,将提交更改为:

    form = getElementById("profileLookupForm");
    $.post(form.action, {paste_data: this.value}, 'script')
    // form.action is the url, `this` is the input field, 'script' tells rails it should render a js script
    

    这样请求是异步完成的,响应不会替换当前页面。

    现在,我认为您正在混合的是 @company_name 不会随着该 ajax 请求而改变。当您呈现表单和其他所有内容时,@company_name 将被替换为那一刻的实际值,并且在您的发布请求后不会更改,因为参考丢失了。所以这一行:

    $('#companyNameTextBox').val("<%= @company_name %>");
    

    将会

    $('#companyNameTextBox').val("");
    

    一直都是。

    您想要的是使用脚本来响应,该脚本使用您设置为 @company_name 的值更新字段(另外,任意等待 X 秒是一种非常糟糕的做法)。

    所以,不要回复:

    format.js { render 'users/lookup_profile'}
    

    使用您要执行的代码创建一个视图lookup_profile.js

    $('#companyNameTextBox').val("<%= @company_name %>");
    

    这里,@company_name 实际上是通过您之前告诉的那些请求获得的值,此时会生成脚本并作为请求的响应执行。

    【讨论】:

    • 感谢您的帮助。无论出于何种原因,当使用您提到的发布数据提交表单时,POST 数据不包含“paste_data”或其值。好像这是最后一件事了。如果我现在按照您的其他说明单击按钮上的提交,则一切正常(包括替换表单文本字段)。
    猜你喜欢
    • 2018-06-23
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 2013-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    相关资源
    最近更新 更多