部分未在第一次点击时更新

时间:2010-11-18 23:49:39

标签: ruby-on-rails

我遇到了远程执行操作的问题,而且部分在第一次点击链接时没有更新。

在视图内部(名为books的部分)我正在创建一个链接:

link_to "⊗", read_book_path(book), :remote => true

read_book_path在routes.rb中定义 还有一个条件,在阅读该书时会显示不同的文本。

在我的控制器中,我定义了一个新动作:

def read
  @books = Book.all
  @book = Book.find(params[:id])
  @book.read = !@book.read
  @book.save
  respond_to do |format|
    format.html { redirect_to(books_url) }
    format.js {render :layout => false, :locals => { :book => @book } }
  end
end

这意味着我需要一个文件read.js.erb,这个文件的内容是:

$("#books").empty().html("<%= escape_javascript( render(:partial => "books") ) %>");

当我点击链接时,我可以在终端窗口中看到数据库字段已更新但部分不是。再次单击相同的链接会更新部分。

将链接更改为:remote => false也可以,但页面会重新加载(如预期的那样)。

我尝试使用Safari和Developer工具调试它,我可以在第一次点击链接时看到服务器的响应。 那里出了点问题,<%= escape_javascript( render(:partial => "books") ) %>生成的HTML包含错误的HTML以及部分的旧内容。只有第二次或第三次点击才会显示更新的HTML。

我已经集成了jquery-ujs - 这是部分第一次没有更新的原因还是我错过了其他的东西?

这让我很头疼,你能帮助我吗?

编辑: 如果这有帮助:我在application.js中创建了一个监听器ajax:beforeajax:complete。第一个显示一个小旋转器,第二个隐藏它。 当我点击链接时,微调器显示但不隐藏。

1 个答案:

答案 0 :(得分:1)

看起来你有一个导致问题的订购问题。您正在将一整套书籍捕获到@books变量中,然后修改单本书的单独副本。此更改不会再传播回来。

# Load and modify the one book by flipping the flag
@book = Book.find(params[:id])
@book.read = !@book.read
@book.save

# Load all books
@books = Book.all

作为一个说明,这是一种效率极低的做事方式,所以我希望你不要处理大量的数据。您可能会发现只需使用简单的UPDATE查询切换一个字段就可以轻松完成此操作:

Book.update_all({ :read => true }, { :id => params[:id] })

我不确定您为什么要调用$(...).empty().html(...)而不是简单$(...).html(...),因为html()方法应该替换HTML批发而不需要事先清除它。

可能有用的一件事是使用等效的.js.rjs

page[:books].replace_html(:partial => 'books')

使用简单的JavaScript,RJS可以消除大量的苦差事。您可以在RJS中使用JS以及没有等效的情况:

page << '$("#books").empty()'
page[:books].replace_html(:partial => 'books')

为了使这个Rails更友好,你可以调用你的部分_book,这会使局部变量变得多余。每个partial都有一个名称与模板名称匹配的默认变量:

render(:partial => 'book', :collection => @books)