2010-11-18 15 views
0

Ich habe Probleme mit einer remote ausgeführten Aktion und eine partielle, die nicht das erste Mal aktualisiert, wenn ich auf den Link klicke.Teil nicht aktualisiert beim ersten Klick

Innerhalb der Ansicht (ein Teil namens books) Ich verursache einen Link:

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

Die read_book_path in definiert ist routes.rb Es gibt auch eine Bedingung, die einen anderen Text anzeigt, wenn das Buch gelesen .

In meinem Controller habe ich eine neue Aktion definiert:

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

Das bedeutet, brauche ich eine Datei read.js.erb, Inhalte dieser Datei ist:

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

Wenn ich auf den Link klicken, kann ich Im Terminalfenster sehen Sie, dass das Datenbankfeld aktualisiert ist, aber das Teilfeld nicht. Wenn Sie erneut auf denselben Link klicken, wird der Teil aktualisiert.

Das Ändern der Verbindung zu :remote => false funktioniert auch, aber die Seite wird neu geladen (wie erwartet).

Ich habe versucht, es mit Safari und den Entwicklertools zu debuggen, und ich kann die Antwort des Servers sehen, wenn ich den Link zum ersten Mal klicke. Da stimmt etwas nicht, der von <%= escape_javascript(render(:partial => "books")) %> generierte HTML enthält den falschen HTML-Code mit dem alten Inhalt des Partiellen. Nur der zweite oder dritte Klick zeigt das aktualisierte HTML.

Ich habe jquery-ujs integriert - ist das der Grund, warum das Teil nicht das erste Mal aktualisiert oder fehlt mir etwas anderes?

Das gab mir wirklich Kopfschmerzen, können Sie mir helfen?

Edit: Wenn das hilft: Ich habe einen Listener in application.js zu ajax:before und ajax:complete erstellt. Der erste zeigt einen kleinen Spinner, der zweite versteckt ihn. Wenn ich auf den Link klicke, wird der Spinner angezeigt, aber er wird nicht ausgeblendet.

Antwort

1

Es sieht so aus, als hätten Sie ein Bestellproblem, das den Ärger verursacht. Sie erfassen einen vollständigen Satz von Büchern in die Variable @books und ändern dann eine separate Kopie eines einzelnen Buches. Diese Änderung wird nicht weitergegeben.

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

# Load all books 
@books = Book.all 

Als Hinweis ist dies eine äußerst ineffiziente Art und Weise, Dinge zu tun, so dass ich hoffe, Sie sind nicht auf eine große Menge von Daten zu arbeiten. Vielleicht finden Sie es einfacher ist, dies mit einer einfachen Abfrage UPDATE die ein Feld Makel, indem Sie einfach zu tun:

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

Ich bin nicht sicher, warum Sie $(...).empty().html(...) anstatt einfach $(...).html(...) seit der html() Methode sind Aufruf soll die HTML ersetzen Großhandel ohne Notwendigkeit, es im Voraus zu klären.

Eine Sache, die helfen könnte, wird .js.rjs mit denen die gleichkäme:

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

Mit einfachen JavaScript, RJS ermöglicht es Ihnen, eine Menge von der Plackerei zu beseitigen. Sie können für die Fälle als auch JS in RJS verwenden, wo es kein Äquivalent:

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

Um diese mehr Rails freundlicher zu machen, könnten Sie Ihre Teil _book nennen, die die lokalen Variablen überflüssig machen würde. Jedes Teil hat eine Standardvariable mit einem Namen, der mit dem Namen der Vorlage übereinstimmt:

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

Vielen Dank für Ihre Antwort. Die Änderung der Reihenfolge hat mein Problem gelöst. :) Was ich versuche zu tun ist eine Art von Schalter, klicken Sie auf ein "lesen" Buch markiert es als "ungelesen" und umgekehrt. Deshalb lese ich den aktuellen Wert, invertiere ihn und speichere ihn zurück. Ich konnte keine bessere Methode finden. – dmnkhhn

Verwandte Themen