当控制器调用format.js

时间:2016-01-06 17:09:11

标签: jquery ruby-on-rails ajax twitter-bootstrap

我有一个模态弹出作为对象的编辑表单。它打开并对控制器说话很好,但是当动作完成时,模态不会关闭。

当控制器呈现新页面时,一切正常,但是当表单(位于模态中)设置为remote:true时,我会遇到问题。

所以模态代码就像 -

boilerplate bootstrap modal markup
id='edit_stream_4'
form_for(@stream, remote: true) do |f|
...etc...
f.submit

......在控制器中我有

def update
  respond_to do |format|
    if @stream.update
      format.js
    ...etc...

...和/streams/update.js.erb

$('#edit_stream_4').modal("hide");
$('#workspace').html("<%= escape_javascript(render :partial => 'streams/show', stream: @stream) %>");

当我点击模态中表单中的更新按钮时,记录会更新,我可以在后台看到部分重新渲染,但模态保持不变。

我想这是因为当我进入控制器时我离开了模态js,并且我放入update.js.erb的js有点垃圾而没有做我想要的事情?< / p>

任何人都可以就如何让我的javascript做我想做的事给我一些建议吗?

感谢您的任何建议。我想我真正想要的是关于处理我认为引导程序与模态之间的冲突的方法的建议[=单击链接以触发模态,当退出模态jQuery关闭它时]和什么Rails正在使用ajax [=部分通过模态循环,使用ajax在页面的其他地方触发div的部分] - 因为我认为通过使用Rails ajax生成我不会正确退出模式。

无论如何,上面的代码片段都是按照它们的方式呈现的,因为我不想把这个问题与应用程序的其他细节混淆 - 但是回应我已经得到的评论,我已经包含了下面的完整代码

该应用程序是我在单页todo上的学习尝试。视口分为两部分 - 上半部分的工作流列表,以及下半部分中与流相关的任务列表。任务呈现为部分,由用户点击上半部分的流链接触发。

所以我的主页是=

container.html.erb

<div id='viewport'>
  <div class='row'>
    <div class='col-md-4'>
      <%= render 'streams/index', streams: @streams %>
    </div>
    <div class='col-md-4'>
      <%= render 'layouts/object_views/index_settings', settings: @settings %>
    </div>
    <div class='col-md-4'>
      <%= render 'layouts/tips' %>
    </div>
  </div>
  <div class='row' id='workspace'>
    <%= render 'layouts/workspace/workspace' %>
  </div>
</div>

首次加载页面时,'layouts / workspace / workspace'部分只包含一个图像:

/layouts/workspace/_workspace.html.erb

<div id='workspace'>
    <%= image_tag("WIN1.png", class:'center-block img-responsive') %>
</div>

流索引包含一些工作流列表,其中包含一些链接=

/streams/_index.html.erb

  <table class='table'>
    <thead>
      <tr>
        <th>Streams</th>
      </tr>
    </thead>
    <tbody>
      <% streams.each do |stream| %>
        <tr>
          <td><strong><%= link_to "#{stream.name}", stream, remote: true %></strong></td>
          <td><%= render 'layouts/components/object_modal', modal_params: {modal_action: :edit, modal_object_class: :stream, modal_object_id: stream.id} %></td>
        </tr>
      <% end %>
      <tr>
        <td>
          <%= render 'layouts/components/object_modal', modal_params: {modal_action: :new, modal_object_class: :stream} %>
        </td>
      </tr>
    </tbody>
  </table>

...你可以看到这部分做了两件事:它遍历@streams,并为每一个提供一个链接,触发控制器上的动作以显示部分 - <%= link_to "#{stream.name}", stream, remote: true %>,和将params传递给通用模态:<%= render 'layouts/components/object_modal', modal_params: {modal_action: :edit, modal_object_class: :stream, modal_object_id: stream.id} %>

模态看起来像这样:

布局/组件/ _object_modal.html.erb

<a href="#" data-toggle="modal" data-target=<%=modal_data_target(modal_params)%>>
  <span><%=modal_params[:modal_alt_title] || "#{modal_params[:modal_action]} #{modal_params[:modal_object_class]}"%></span>
</a>

<div class="modal fade bannerformmodal" tabindex="-1" role="dialog" aria-labelledby="bannerformmodal" aria-hidden="true" id=<%=modal_id(modal_params)%>>
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title" id="myModalLabel"><%=modal_title(modal_params)%></h4>
      </div>
      <div class="modal-body">
        <%= render partial: "#{modal_params[:modal_object_class]}s/#{modal_params[:modal_action]}", locals: {id: modal_params[:modal_object_id], parent_id: modal_params[:parent_id]} %>
      </div>
    </div>
  </div>
</div>

所有这一切都是调用几个助手来插入正确的id等,然后用模态体中的实际形式调用部分:<%= render partial: "#{modal_params[:modal_object_class]}s/#{modal_params[:modal_action]}", locals: {id: modal_params[:modal_object_id], parent_id: modal_params[:parent_id]} %>

这部分解包了确定类,动作和对象id的参数,并调用适当的形式和动作。以这种方式做事是有充分理由的 - 它将允许用户以多种不同的方式对任务进行分组,这是练习的重点。因此,例如,如果您在流类上调用edit方法,则会得到以下形式:

流/ _edit.html.erb

<%= bootstrap_form_for(stream = Stream.find_by_id(id), remote: true) do |f| %>
  <% if stream.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(stream.errors.count, "error") %> prohibited this stream from being saved:</h2>

      <ul>
      <% stream.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.text_field :name %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
<%= button_to 'Delete Stream', stream_path(stream), method: :delete, class: 'btn btn-danger', data: { confirm: "Are you sure?" }  %>

...这在控制器中:

  def edit
  end

  def update
    respond_to do |format|
      if @stream.update(stream_params)
        # format.html { redirect_to whatisnext_path, notice: 'Stream was successfully updated.' }
        # format.json { render :show, status: :ok, location: @stream }
        format.js
      else
        format.html { render :edit }
        format.json { render json: @stream.errors, status: :unprocessable_entity }
      end
    end
  end

...触发以下js -

流/ update.js.erb

$('#viewport').html("<%= escape_javascript(render 'whatisnext_signed_in_dynamic' %>");

......意图是我们离开模态并返回主视图。一切都发生得很好,直到用户点击提交按钮 - 对象被更新并且更改保存到数据库,但问题是模态只是悬挂。

所以问题是 - 如何让Rails ajax和bootstrap jQuery很好地运行,以便模态关闭呢?

2 个答案:

答案 0 :(得分:3)

我在编辑功能上使用模态也有类似的问题,我的更新可以正常工作,但模型没有正确关闭,留下一个黑暗的透明页面。在我的情况下,在update.js.erb中添加以下内容解决了这个问题。

$(".modal-backdrop").remove();

答案 1 :(得分:0)

尝试使用此jQuery代码并更新元素以匹配您的项目。

由于模态表单设置为Book,因此代码通过AJAX POST将信息提交给Rails。

要结合此过程,可以绑定一个remote: true事件,然后关闭模态窗口。

ajax:success