通过javascript进行部分更新

时间:2014-08-03 02:30:21

标签: javascript jquery ruby-on-rails

我在Ruby on Rails上冒险了一段时间但从未对js做过任何事情。我在互联网上搜索了一些教程,但没有任何内容符合我想要的内容。

我有一个rails应用程序,在一个视图中我有两个部分,一个表单和另一个表单,显示由表单创建的任务列表。我希望在单击提交按钮时,使用新创建的新任务更新部分列表,同时保留之前创建的其他任务。

任何人都有更好的链接来帮助我吗?还是有点时间向我解释一下?

修改

借助以下答案,我将代码更改为:

_to_do_list.html.erb(使用部分表单,它应该更新下面的表单,按下按钮子表单时列出。)

<%= form_for @todo_list, remote: true do |f| %>
....
<div class="field">
      <%= f.label :name%><br />
      <%= f.text_field :name %>
    </div>
    <div class="field">
      <%= f.label :description %><br />
      <%= f.text_area :description %>
    </div>

    <div class="field">
      <%= f.label 'Público?'%>
      <%= f.check_box :is_public %>
    </div>

    <div class="actions">
      <%= f.submit %>
    </div>
    <div id= "show_list"> 
      <%= render 'show'  %> 
    </div>

并且,部分显示,未更改,必须更新:

<table id="list" border="1" >
  <tr>
    <th>Name</th>
    <th>Description</th>
    <th>is public?</th>
    <th>Add Tasks</th>
    <th>erase List</th>
  </tr>
  <% @todo_lists.each do |f|%>
  <tr>
    <td><%=f.name %></td>
    <td><%=f.description%></td>
    <td><%=f.is_public  %></td>
    <td><%= link_to new_task_path :method => :get %></td>
    <td> <%= link_to 'Destroy', f, confirm: 'Are you sure?', method: :delete%></td>
  </tr>
  <% end %>
</table>

并且,新的js文件:

$("#todos").html('<%=j render partial: "to_do_lists/show", locals: { todo_lists: @todo_list } %>');

控制器:

def create
    @todo_list = ToDoList.new(params[:to_do_list])
    @todo_list.member_id = current_member.id

    respond_to do |format|
      if @todo_list.save
        format.js{}
        format.html { redirect_to @todo_list, notice: 'Lista ' +@todo_list.name+ ' foi criada com sucesso!' }
        format.json { render json: @todo_list, status: :created, location: @todo_list }
      else
        format.html { render action: "new" }
        format.json { render json: @todo_list.errors, status: :unprocessable_entity }
      end
    end
  end

这个想法是在表中创建一个新行,创建新任务而不离开页面。

谢谢。

修改

2 个答案:

答案 0 :(得分:1)

您需要的是AJAX。如果你看一下它说的文件

JavaScript can also make requests to the server, and parse the response. It also has the ability to update information on the page. Combining these two powers, a JavaScript writer can make a web page that can update just parts of itself, without needing to get the full page data from the server. This is a powerful technique that we call Ajax.

要实现此目的,您首先需要更改表单,使其具有 remote: true 选项,基本上允许您的表单值由js提交。您的表单看起来像

<%= form_for @todo_list, remote: true do |f| %>
  ...
  // form fields
<% end %>

<div id= "some-id"> // to target this div to render your partial from js
  <%= render 'show'  %>  // it doesn't make sense to have your partial inside form and 
</div>

它应该在你的表格之外

在您的创建操作中,您需要 respond_to 阻止

def create
  @todo = Todo.new(todo_params)
  respond_to do |format| 
    if @todo.save
      format.js{}  # this will allow rails to look for create.js.erb in your views/controller directory where you can use your js to render your partial or append newly created todo
    else
      format.html{render "new"}
    end
  end
end

在你的create.js.erb模板中使用你的js渲染部分或附加新创建的项目

$("#some-id").html("<%=j render "show" %>");

不是再次渲染整个部分,而是通过js将新创建的待办事项附加到表中

$("#table-id").append("<%=j render partial: "todo", locals: {f: @todo} %>");

此处_todo.html.erb将包含

<tr>
  <td><%=f.name %></td>
  <td><%=f.description%></td>
  <td><%=f.is_public  %></td>
</tr>

详情结帐Working with javascript in rails

<强>更新

如果你看看你的部分,你有

<table id="list" border="1" >
  <% @todo_lists.each do |f|%> // your @todo_lists is a collection of todos 
    <tr>
      <td><%=f.name %></td>
      <td><%=f.description%></td>
      <td><%= link_to new_task_path %></td> // you don't need to specify method here link_to by default uses a get request
      <td> <%= link_to 'Destroy', f, confirm: 'Are you sure?', method: :delete%></td>
    </tr>
  <% end %>
</table>

将您的控制器方法更改为:

def create
  @todo_list = ToDoList.new(params[:to_do_list])
  @todo_list.member_id = current_member.id
  respond_to do |format|
    if @todo_list.save
      @todo_lists = ToDoList.all // get a collection of todos to render in your partial
      format.js{}
      format.html { redirect_to @todo_list, notice: 'Lista ' +@todo_list.name+ ' foi criada com sucess!' }
      format.json { render json: @todo_list, status: :created, location: @todo_list }
    else
      format.html { render action: "new" }
      format.json { render json: @todo_list.errors, status: :unprocessable_entity }
    end
  end
end

在你的create.js.erb文件中

$("#show_list").html('<%=j render partial: "to_do_lists/show", locals: { todo_lists: @todo_lists } %>'); //You don't have an element with id = todos. You have it with show_lists so change that

在关闭表单后再渲染部分内容。在表单中显示待办事项是没有意义的

答案 1 :(得分:1)

  

我希望在单击提交按钮时,部分列表是   使用新创建的新任务进行更新,同时保留其他任务   之前创建的。

这确实可以通过ajax

实现

-

<强>的Ajax

Ajax (Asynchronous Javascript And XML)基本上是一种从JS向你的后端发送伪请求的方法。

由于您是Rails的新手,让我解释一下无状态的想法。 Stateless applications(构成大多数使用HTTP协议构建的)将每个请求视为“新” - 不存储任何个性化详细信息以供每次使用

这意味着如果您想在不重新加载页面的情况下向Rails发送请求,则需要发送接收数据,并将其附加到已加载的页面。这就是Ajax的作用。

-

<强>滑轨

你问的是相对简单的

您需要执行以下操作:

  
      
  1. 使用ajax
  2. 将表单数据发送到Rails   
  3. 在Rails后端,捕获事件,执行功能&amp;响应
  4.   
  5. 在你的前端,“倾听”回应&amp;附加到页面
  6.   

有很多方法可以实现这一目标。为简单起见,我将详细介绍实现它的最直接方法(这使用Rails UJS driver):

#app/views/todo_lists/new.html.erb
<%= form_for(@todo_list), remote: true do |f| %>

这将捕获您的表单submit操作&amp;将更新发送到所需的URL。这意味着您将能够在控制器中捕获请求。然后在后端处理它:

#app/controllers/todo_lists_controller.rb
Class TodoListsController < ApplicationController
   def create
      @todo_list = TodoList.new(todo_params)
      @todo.save

      respond_to do |format|
         format.js #-> loads /views/todo_lists/create.js.erb
         format.html
      end
   end
end

这将允许您拨打以下电话:

#app/views/todo_lists/create.js.erb
$("#todos").html('<%=j render partial: "todo_lists/your_partial", locals: { todo_lists: @todo_lists }" %>');

这将为用户调用您的JS - 将请求附加到您的视图;使它看起来像不需要刷新:)