35

Mam model Backbone.js, który próbuję zniszczyć, gdy użytkownik kliknie łącze w widoku modelu. Widok jest podobny do tego (pseudokod, ponieważ jest zaimplementowany w CoffeeScript, który można znaleźć na dole pytania).Backbone model.destroy() wywołujący funkcję wywołania błędu, nawet jeśli działa poprawnie?

var window.ListingSaveView = Backbone.View.extend({ 
    events: { 
    'click a.delete': 'onDestroy' 
    }, 

    onDestroy: function(event){ 
    event.preventDefault(); 
    this.model.destroy({ 
     success: function(model, response){ 
     console.log "Success"; 
     }, 
     error: function(model, response){ 
     console.log "Error"; 
     } 
    }); 
    } 
}); 

Kiedy klikam odnośnik w przeglądarce delete, zawsze dotrzesz Error zalogowany do konsoli, chociaż moje rekordy serwera udany zniszczenia związanego rekordu bazy danych i zwraca odpowiedź 200. Po odświeżeniu strony (powodując ponowne renderowanie kolekcji z bazy danych) usunięty zostanie model, który usunąłem.

Jednym z interesujących jest to, że po zalogowaniu response w wywołaniu błędu kod statusu 200 wskazuje na sukces, ale również zgłasza statusText: "parseerror" cokolwiek to oznacza. W moich dziennikach serwera nie ma błędów.

Co robię źle?

To jest odpowiedź z serwera:

Object 
    abort: function (statusText) { 
    always: function() { 
    complete: function() { 
    done: function() { 
    error: function() { 
    fail: function() { 
    getAllResponseHeaders: function() { 
    getResponseHeader: function (key) { 
    isRejected: function() { 
    isResolved: function() { 
    overrideMimeType: function (type) { 
    pipe: function (fnDone, fnFail) { 
    promise: function (obj) { 
    readyState: 4 
    responseText: " " 
    setRequestHeader: function (name, value) { 
    status: 200 
    statusCode: function (map) { 
    statusText: "parsererror" 
    success: function() { 
    then: function (doneCallbacks, failCallbacks) { 
    __proto__: Object 

Oto działanie serwera, który zniszczy współdziała z (Ruby on Rails)

# DELETE /team/listing_saves/1.json 
    def destroy 
    @save = current_user.team.listing_saves.find(params[:id]) 
    @save.destroy 
    respond_to do |format| 
     format.json { head :ok } 
    end 
    end 

I tu jest faktyczna realizacja coffeescript szkieletu Widok dla osób, które preferują to:

class MoveOutOrg.Views.ListingSaveView extends Backbone.View 
    tagName: 'li' 
    className: 'listing_save' 
    template: JST['backbone/templates/listing_save'] 
    events: 
    'click a.delete_saved': 'onDestroy' 

    initialize: -> 
    @model.bind 'change', this.render 
    render: => 
    renderedContent = @template(@model.toJSON()) 
    $(@el).html(renderedContent) 
    this 
    onDestroy: (event) -> 
    event.preventDefault() # stop the hash being added to the URL 
    console.log "Listing Destroyed" 
    @model.destroy 
     success: (model, response)-> 
     console.log "Success" 
     console.log model 
     console.log response 

     error: (model, response) -> 
     console.log "Error" 
     console.log model # this is the ListingSave model 
     console.log response 
+0

Czy możesz wkleić wszystko, co serwer odsyła (użyj firebuga lub czegoś, aby otworzyć odpowiedź), jeśli w ogóle coś takiego? – Stephen

+0

Zmieniono moje pytanie w celu uwzględnienia odpowiedzi –

+1

Och. Cóż, żeby być szczerym ... to nie jest poprawna odpowiedź. Najprawdopodobniej nasłuchuje odpowiedzi JSON .. i tak czy inaczej nie dajesz jej. Nie pamiętam, co używamy w pracy na szynach, ale jest to coś w stylu to_json, nie tylko "json" (nie jestem ekspertem od rubinów .. ani nawet początkującym .. więc nie mogę pomóc, że przeszłam) – Stephen

Odpowiedz

51

@David Tuite comm ent:

"Ok, wymyśliłem to. Wygląda na to, że Backbone oczekuje, że odpowiedzią JSON będzie serializacja JSON rekordu, który został zniszczony. Jednak generatory kontrolerów Railsów zwracają jedynie wartość head: ok domyślnie. Zmieniłam moją odpowiedź JSON za renderowanie JSON: @listing_save gdzie @listing_save jest zapis po prostu zniszczone i rejestruje się sukcesem „

FYI - kiedy robisz zniszczyć, nie trzeba. zwróć pełny json dla zniszczonego modelu, możesz zwrócić pusty skrót json i będzie działać dobrze, jedyny czas, kiedy musisz zwrócić json dla modelu, jest zapisany/zaktualizowany

+3

ok, możesz mieć punkty. Nawet jeśli zrobiłem połowę pracy;) –

+0

kręgosłup jest tak czuły na wynik JSL w szynach –

+2

Chociaż nie trzeba zwracać modelu, czasami jest to całkiem miłe. Jeden przypadek, w którym jest to miłe podejście, to gdy nie używasz parametru {wait: true} niszczenia - w ten sposób, jeśli akcja się nie powiedzie, możesz łatwo ponownie dodać model do kolekcji, aby zachować kolekcję zaktualizowany. –

0

Czy jesteś pewien Twój adres URL? Czy dołączasz .json na końcu adresu URL Backbone.Model? Ponieważ sprawdzisz to po swojej stronie serwera (response_to do | format | ... end), możesz nie wysłać prawidłowej odpowiedzi

Spróbuj z tej metody destroy szyn aby sprawdzić, czy jest to problem:

def destroy 
    @save = current_user.team.listing_saves.find(params[:id]) 
    @save.destroy 
    head :ok 
end 
7

Twoja odpowiedź musi mieć kod statusu 204, jak nie zwróci żadnych treści. Ponieważ szkielet używa interfejsu REST, powinieneś zwracać różne kody stanu http w zależności od zadania.

16

Miałem ten sam problem. W mojej metodzie usuwania na serwerze (java) nic nie zwracałem. Tylko status 200/OK (lub 204/Brak treści). I tak problem "parsererror" został spowodowany przez jquery próbujący przekonwertować pustą odpowiedź na JSON, co nie powiodło się (ponieważ "json" jest domyślnym typem danych).

Moje rozwiązanie było użyć „tekst” dataType zamiast, który można ustawić w opcjach:

model.destroy({ dataType: "text", success: function(model, response) { 
    console.log("success"); 
}}); 
+0

Przyjemny połów. Dziękuję Ci. – chikamichi

+2

Użyłem również 'model.destroy ({contentType: false, processData: false})'. – carpeliam

0

za pomocą ramy Slim na serwerze LAMP można dodać Response Status do DELETE trasy (lub na zamówienie trasy, które nic nie Return)

$app->response()->status(204);//204 No Content

ten określa również Content-Type z powrotem do text/html, aby umożliwić pustego korpusu

Powiązane problemy