我遇到了远程执行操作的问题,而且部分在第一次点击链接时没有更新。
在视图内部(名为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:before
和ajax:complete
。第一个显示一个小旋转器,第二个隐藏它。
当我点击链接时,微调器显示但不隐藏。
答案 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)