2014-10-09 32 views
2

每當我在我的Rails應用中點擊提交,它都會發送請求2x。我可以通過刷新來擺脫第二部分。這是一個嵌套的應用程序。 Todo has_many項目。我包括控制器和創建和部分。 我收錄了一張照片,讓它更清晰一些。 enter image description hereRails 4 Ajax每次在同一頁面上多次呈現多次提交提交

create.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) 

回答

0

問題是與你的create.js.erb文件。你有下面的代碼:在todo-items

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

在這段代碼中,你是預未決HTML就應該更換的物品,每次來代替。如下所示:

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

這將每次都用新的html代替html。

+0

謝謝!這是我第一次和Ajax合作。關於我可以在哪裏瞭解更多的任何建議? – 2014-10-09 12:35:34

+0

你可以學習你的經驗。我也在這裏從專家的問題和答案中學習。 – 2014-10-09 13:13:54

+0

codeschool($ 29/month)jQuery課程級別1和級別2爲學習AJAX提供了演講練習方法。無論如何,你的問題是使用jQuery - 而不是AJAX。 – dwilbank 2014-10-11 05:02:59