Ajax和Rails 4:创建实例变量并更新视图而不刷新

时间:2017-07-14 23:46:31

标签: jquery ruby-on-rails ajax ruby-on-rails-4

我有一部分coaching_notes索引,其中包含一个用于创建笔记的表单。我想创建一个教练笔记,并在没有页面刷新的情况下进行部分更新。我收到一个未知操作错误:无法找到CoachingNotesController的操作'show'。如果我添加show动作,则会出现模板丢失错误。当我尝试从控制器中删除format.html部分时,我也遇到了未知的格式错误。

我在Rails文档之后对我的代码进行了建模,并且还审查了一些类似的情况但无法使其工作。

非常感谢任何帮助!!!

/views/coaching_notes/_index.html.erb

<div id="coaching_notes">
  <% @coaching_notes.each do |note| %>
    <li> <%= note.content %> </li>
  <% end %>
</div>
<br>
<% @coaching_note = CoachingNote.new(user_id: current_user.id, meeting_id: session[:current_meeting_id]) %>
<%= form_for(@coaching_note, remote: true) do |f| %>

  <%= f.hidden_field :user_id %>
  <%= f.hidden_field :meeting_id %>
  <%= f.hidden_field :archive %>
  <%= f.text_field :content %>

  <%= f.submit %>
<% end %>

/views/coaching_notes/_coaching_note.html.erb

<li><%= note.content %></li>

/views/coaching_notes/create.js.erb

$("<%= escape_javascript(render coaching_note) %>").appendTo("#coaching_notes");

/controllers/coaching_notes_controller.rb

def create
@coaching_note = CoachingNote.new(coaching_note_params)

respond_to do |format|
  if @coaching_note.save
    format.html { redirect_to @coaching_note, notice: 'note was successfully created.' }
    format.js   {}
    format.json { render json: @coaching_note, status: :created, location: @coaching_note }
  else
    format.html { render action: "new" }
    format.json { render json: @coaching_note.errors, status: :unprocessable_entity }
  end
end

的routes.rb

resources :coaching_notes

更新7/15/17   - 我根据@ Cira的答案修改了几个文件:

/views/coaching_notes/_index.html.erb

<div id="coaching_notes">
  <% @coaching_notes.each do |note| %>
    <li> <%= note.content %> </li>
    <%= link_to "delete", note, :remote => true, :method => :delete, :data => {:confirm => "Are you sure?"} %>
  <% end %>
</div>
<br>
<% @coaching_note = CoachingNote.new(user_id: current_user.id, meeting_id: session[:current_meeting_id]) %>
<%= form_for(@coaching_note, remote: true) do |f| %>

  <%= f.hidden_field :user_id, id: 'user' %>
  <%= f.hidden_field :meeting_id, id: 'meet' %>
  <%= f.hidden_field :archive, id: 'arch' %>
  <%= f.text_field :content, id: 'content' %>

  <%= f.submit 'Add note', id: 'submit_note' %>
<% end %>

// newly added
<script>
$('#submit_note').on( "click", function() {
  var u = $('#user').val()
  var m = $('#meet').val()
  var a = $('#arch').val()
  var c = $('#content').val()

  $.ajax({
    url: "/coaching_notes/create",
    type: "POST",
    data: {
      user_id: u,
      meeting_id: m,
      archive: a,
      content: c
    },
    dataType: "json",
    success: function(info) {
      $('#coaching_notes').data( "html", info )
    }
  });
})
</script>

我不知道的主要部分是数据属性的成功函数

/controllers/coaching_notes_controller.rb

def create
    @coaching_note = CoachingNote.new(coaching_note_params)

    @html = render_to_string :partial => "coaching_notes/index"
    respond_to do |format|
      if @coaching_note.save
        format.html
        format.json { render json: {"html" => @html} }
      else
        format.html { render action: "new" }
        format.json { render json: @coaching_note.errors, status: :unprocessable_entity }
      end
    end

两件事: 1.我的成功功能在ajax中是否正确? 2.我是否需要将if @coaching_note.save放入控制器?

我现在得到的错误是'CoachingNotes中的NoMethodError #create - 未定义的方法`每个'为nil:NilClass'突出显示coaching_notes / index.html中的这一行

<% @coaching_notes.each do |note| %>

然后我得到'缺少模板coaching_notes / index'

我觉得我们越来越近了!任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:0)

我认为你可以做的是当用户按下提交按钮时,可以通过AJAX将表单的数据传递给控制器​​动作(创建)

$.ajax({
                    url: "/coaching_notes/create",
                    type: "POST",
                    data: {a hash of the data retrieved from the inputs},
                    dataType: "json",
                    success: function(data) {
                        //replace data of div you want here using String(data["html"], html being the attribute passed back via json from the controller.
                    }
                });

并在您的控制器中创建教练笔记之后再次渲染部分:

@html = render_to_string :partial => "coaching_notes/index"
      respond_to do |format|
        format.html
        format.json {render json: {"html" => @html}}
      end

使用AJAX将HTML发送回视图,并在ajax成功函数下替换原始教练备注的HTML。

干杯!

答案 1 :(得分:0)

事实证明问题是我在我的应用程序中错过了这一行.js:

 //= require jquery_ujs

对于那些不知道的人,ujs代表'Unobtrusive JavaScript'。如果不这样做,remote: true将没有多大帮助。

在弄清楚之前,我确实找到了一个只使用javascript和ajax的解决方案,这里是删除笔记的脚本:

$("input[value='Del']").click(function(event){
  event.preventDefault();
  var num = this.id
    $.ajax({
        type: "DELETE",
        url: "/coaching_notes/" + this.id,
        dataType: "json",
        success: function(data){
          // remove the div containing the note
        }
    });
});

请注意,您需要使用preventDefault()来阻止表单提交。

添加注释的脚本肯定可以进行更多重构,但仍然有效:

$(document.body).delegate('input:text', 'keypress', function(e) {
    // if user hits enter key
    if (e.which === 13) {
        e.preventDefault();
      createNote()
    }
})

$("#submit_note").click(function(e) {
  e.preventDefault()
  createNote()
})

function createNote() {
  var u = $('#user').val()
  var m = $('#meet').val()
  var a = $('#arch').val()
  var c = $('#content').val()

  if (c != "") {
    $.ajax({
      url: "/coaching_notes",
      type: "POST",
      data: {
        "coaching_note": {
          "user_id": u,
          "meeting_id": m,
          "archive": a,
          "content": c
        }
      },
      dataType: "json",
      success: function(note) {
        $("#content").val('') // clears the input box
        // add the new note here
      }
    });
  }
} 

关于委派按键的部分是当用户点击“输入”键时发送的注释。同样,e.preventDefault()阻止通过Rails提交表单。

希望这有助于他人!我知道我已经坚持了一段时间,这是一个非常简单的解决方案。别忘了! 请确认您已经在申请中了.JS!

 //= require jquery_ujs

由于