javascript - 每次提交时,Rails 4 Ajax 在同一页面上多次渲染部分

标签 javascript ruby-on-rails ajax ruby-on-rails-4

每次我在 Rails 应用程序中点击提交时,它都会发送 2 次请求。我可以通过点击刷新来摆脱第二部分。这是一个嵌套的应用程序。 Todo 有_many 个项目。我包括了 Controller 以及创建和部分。 我附上了一张照片,以便更清楚一点。 enter image description here

创建.js.erb

$('.todo-items').prepend("<%= escape_javascript(render(@item)) %>");

Items Controller:

class ItemsController < ApplicationController
  before_action :set_item, only: [:show, :edit, :update, :destroy]
  before_action :set_todo
  respond_to :html, :js

  # GET /items
  # GET /items.json
  def index
    @items = Item.all
  end

  # GET /items/1
  # GET /items/1.json
  def show
    @item = Item.find(params[:id])
  end

  # GET /items/new
  def new
    @item = @todo.items.build
  end

  # GET /items/1/edit
  def edit
    @item = Items.find(params[:id])
  end

  # POST /items
  # POST /items.json
  def create
    @item = @todo.items.build(item_params)

    respond_with(@item) do |format|
      if @item.save
        format.html { redirect_to [@todo], notice: 'Item was successfully created.' }
        format.json { render :show, status: :created, location: @item }
      else
        format.html { render :new }
        format.json { render json: @item.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /items/1
  # PATCH/PUT /items/1.json
  def update
    @item = Item.find(params[:id])
    respond_to do |format|
      if @item.update(item_params)
        format.html { redirect_to [@todo, @item], notice: 'Item was successfully updated.' }
        format.json { render :show, status: :ok, location: @item }
      else
        format.html { render :edit }
        format.json { render json: @item.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /items/1
  # DELETE /items/1.json
  def destroy
    @item = Item.find(params[:id])
    @item.destroy

    respond_to do |format|
      format.html { redirect_to items_path }
      format.json { head :no_content }
      format.js   { render layout: false }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_item
      @item = Item.find(params[:id])
    end

    def set_todo
      @todo = Todo.find(params[:todo_id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def item_params
      params.require(:item).permit(:content, :todo_id)
    end
end

Todos Controller

class TodosController < ApplicationController
  respond_to :html, :js
  before_action :set_todo, only: [:show, :edit, :update, :destroy]

  # GET /todos
  # GET /todos.json
  def index
    @todos = Todo.all
    @todo = Todo.new
  end

  # GET /todos/1
  # GET /todos/1.json
  def show
    @todo= Todo.find(params[:id])
  end

  # GET /todos/new
  def new
    @todo = Todo.new
    #3.times{@todo.items.build}
  end

  # GET /todos/1/edit
  def edit
  end

  # POST /todos
  # POST /todos.json
  def create
    @todo = Todo.new(todo_params)
    #@todo.items.build

    respond_to do |format|
      if @todo.save
        format.html { redirect_to todo_path, notice: 'Todo was successfully created.' }
        format.json { render :show, status: :created, location: @todo }
      else
        format.html { render :new }
        format.json { render json: @todo.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /todos/1
  # PATCH/PUT /todos/1.json
  def update
    @todo = Todo.find(params[:id])
    respond_to do |format|
      if @todo.update(todo_params)
        format.html { redirect_to todos_url, notice: 'Todo was successfully updated.' }
        format.json { render :show, status: :ok, location: @todo }
      else
        format.html { render :edit }
        format.json { render json: @todo.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /todos/1
  # DELETE /todos/1.json
  def destroy
    @todo.destroy
    @todo.items.destroy
    respond_to do |format|
      format.html { redirect_to todos_url, notice: 'Todo was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  def todo_completed
    @todo = Todo.find(params[:id])
    @todo.completed = true

    if @todo.save
      flash[:notice] = "Task was completed."
    else
      flash[:error] = "There was an error completing the task."
    end
    #redirect_to tasks_path

    respond_with(@todo) do |f|
      f.html { redirect_to todos_path }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_todo
      @todo = Todo.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def todo_params
      params.require(:todo).permit(:title, :completed, items_attributes: [:content,:completed, :_destroy])
    end
end

这是照片中 Todo 的展示页面。它正在呈现特定待办事项下方的项目。

<p>Here are all the things you need to complete</p>

<div class="todo-items">
    <%= render partial: 'items/item' %>
</div>

<br>
<div class='new-item'>
  <%= render 'items/form'%>
</div>

<%= link_to 'Back', todos_path %>

项目/项目

<p>todo/show this is the partial <%= @todo.title %></p>
<table class='table table-bordered'>
  <thead>
    <tr>
      <th>Description</th>
      <th> Time Left </th>
      <th> Mark Complete </th>
    </tr>
  </thead>

  <tbody>
    <% @todo.items.each do |item| %>
      <tr>
        <td><%= link_to item.content, [@todo, item] %></td>
        <td><%= item.days_left %>
        <td>
            <%= link_to todo_item_path(@todo,item), method: :delete, data: { confirm: 'Are you sure?' }, remote: true, class: 'delete_item' do %>
                <i class="fa fa-check"></i>
            <% end %>
        </td>    
      </tr>
    <% end %>
  </tbody>
</table>

<br>
<p>end of partial item</p>

项目/形式

<p>
  <strong>Todo:</strong>
  <%= @todo.title %>
</p>

<%= form_for [@todo, @todo.items.build], remote: true do |f| %>
  <div class="field">
    <%= f.label :content %><br>
    <%= f.text_field :content %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

来自控制台的更多信息。当我点击列表(杂货)时开始,最后我点击提交添加项目

Started GET "/todos/25" for 127.0.0.1 at 2014-10-08 19:19:58 -0500
Processing by TodosController#show as HTML
  Parameters: {"id"=>"25"}
  Todo Load (0.3ms)  SELECT  "todos".* FROM "todos"  WHERE "todos"."id" = ? LIMIT 1  [["id", 25]]
  CACHE (0.0ms)  SELECT  "todos".* FROM "todos"  WHERE "todos"."id" = ? LIMIT 1  [["id", "25"]]
  Item Load (0.4ms)  SELECT "items".* FROM "items"  WHERE "items"."todo_id" = ?  [["todo_id", 25]]
  Rendered items/_item.html.erb (42.9ms)
  Rendered items/_form.html.erb (17.3ms)
  Rendered todos/show.html.erb within layouts/application (66.6ms)
Completed 200 OK in 346ms (Views: 339.5ms | ActiveRecord: 1.3ms)


Started POST "/todos/25/items" for 127.0.0.1 at 2014-10-08 19:20:12 -0500
Processing by ItemsController#create as JS
  Parameters: {"utf8"=>"✓", "item"=>{"content"=>"Cereal"}, "commit"=>"Create Item", "todo_id"=>"25"}
  Todo Load (0.2ms)  SELECT  "todos".* FROM "todos"  WHERE "todos"."id" = ? LIMIT 1  [["id", 25]]
   (0.3ms)  begin transaction
  Todo Load (0.2ms)  SELECT  "todos".* FROM "todos"  WHERE "todos"."id" = ? LIMIT 1  [["id", 25]]
  SQL (0.5ms)  INSERT INTO "items" ("content", "created_at", "todo_id", "updated_at") VALUES (?, ?, ?, ?)  [["content", "Cereal"], ["created_at", "2014-10-09 00:20:12.060569"], ["todo_id", 25], ["updated_at", "2014-10-09 00:20:12.060569"]]
   (148.1ms)  commit transaction
  Item Load (0.2ms)  SELECT "items".* FROM "items"  WHERE "items"."todo_id" = ?  [["todo_id", 25]]
  Rendered items/_item.html.erb (9.8ms)
  Rendered items/create.js.erb (12.5ms)
Completed 200 OK in 180ms (Views: 15.2ms | ActiveRecord: 149.4ms)

最佳答案

问题出在您的 create.js.erb 文件上。您有以下代码:

$('.todo-items').prepend("<%= escape_javascript(render(@item)) %>");

在这段代码中,您在 todo-items 中预先挂起 html,您应该每次都替换项目。如下所示:

$('.todo-items').html("<%= escape_javascript(render(@item)) %>");

这将每次用新的 html 替换 html。

关于javascript - 每次提交时,Rails 4 Ajax 在同一页面上多次渲染部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26268382/

相关文章:

javascript - Jest 中的 XMLHttpRequest 测试

javascript - 当我点击标签时传递 jquery 参数

ruby-on-rails - Rails 3 数组 :Class 的未定义方法 `model_name'

ruby-on-rails - 如果 rspec 测试失败,则启动 ruby​​ 调试器

html - 我可以申请远程 : true to an html href link?

javascript - onkeyup 激活很多ajax请求

javascript - 流程图呈现意外

使用 FileReader 和 Promise 时的 JavaScript 内存泄漏

Javascript window.open 函数打开 json feed 中的所有 url

ruby-on-rails - 如何使用 ruby​​ on rails 生成人类可读的时间范围