2016-10-06 6 views
1

Ich habe zwei Ansichten - eine Layout-Ansicht, die oberste Ebene ist, und eine neue Formularansicht, die als untergeordnetes Element für das Layout fungiert und darin gerendert wird. Ich habe einen Ereignishandler in der Formularansicht, der eine neue Instanz meines Modells gemäß den Daten aus der Eingabe erstellen soll.Backbone-Ereignishandler funktioniert nicht

Hier ist die Layout-Ansicht:

var LayoutView = Backbone.View.extend({ 
    el: "#layout", 
    render: function (view) { 
     this.child = view; 
     if (this.child) { 
      this.child.remove(); 
     } 
     this.$el.html(this.child.render().el); 
     return this; 
    } 
}); 

und hier ist meine Form Ansicht:

var ResumeForm = Backbone.View.extend({ 
    events: { 
     'click #create': 'createResume' 
    }, 
    initialize: function() { 
     this.template = _.template($('#new-resume').html()); 
    }, 
    render: function() { 
     this.$el.html(this.template()); 
     return this; 
    }, 
    createResume: function() { 
     // getting values from template inputs and saving them to model 
     var resume = new Resume({ 
      profession: $('#profession').val(), 
      firstName: $('#firstname').val(), 
      lastName: $('#lastname').val() 
     }); 
     // saving a new model to collection instance 
     resumes.add(resume); 
     resume.save(null, { 
      success: function (res) { 
       console.log("POST resume id " + res.toJSON().id); 
      }, 
      error: function() { 
       console.log("Failed to POST"); 
      } 
     }); 
    } 
}); 

Meine Form Ansicht perfekt in meinem Layout-Ansicht macht, aber wenn ich die Werte eingeben und #create Schaltfläche klicken, nichts passiert - weder speichert das Modell noch protokolliert einen Fehler Fehler von meiner createResume Methode. Ich vermute, dass beim Rendern einer Formularansicht in der Layoutansicht die Zeile this.$el.html(this.child.render().el); nur alle Ereignislistener zerstört, denn wenn ich diese Listener zur Layoutansicht hinzufüge, funktioniert es.

Gibt es Möglichkeiten, dieses Problem zu beheben?

Antwort

1

Backbones Ansicht remove Funktion undelegates die Ereignisse an die el gebunden.

Vom annotated source:

remove: function() { 
    this._removeElement(); 
    this.stopListening(); 
    return this; 
}, 

_removeElement: function() { 
    this.$el.remove(); 
}, 

Diese mit jQuery .remove() Funktion zu tun hat (Hervorhebung von mir):

Similar to .empty() , the .remove() method takes elements out of the DOM. Use .remove() when you want to remove the element itself, as well as everything inside it. In addition to the elements themselves, all bound events and jQuery data associated with the elements are removed. To remove the elements without removing data and events, use .detach() instead.

Wenn Sie remove aufrufen, bevor die Ansicht Wiederverwendung, müssen Sie das manuell aufrufen this.delegateEvents(), um die Ereignisse aus dem Hash events erneut zu binden und jedes Ereignis erneut zu verkabeln, über das die Ansicht angehört wurde this.listenTo(...).

Aber der beste Weg Ansichten wiederverwenden, ohne remove Aufruf, die stopListening nennt, können Sie setElement verwenden, welche die Ereignisse undelegates, und die zu dem übergebenen Element View-Element ändern, dann die Ereignisse erneut Delegierten.

setElement: function(element) { 
    this.undelegateEvents(); 
    this._setElement(element); 
    this.delegateEvents(); 
    return this; 
}, 

Ihre LayoutView wäre so etwas wie dies geworden:

var LayoutView = Backbone.View.extend({ 
    el: "#layout", 
    render: function(view) { 
     // if the view is different, make sure to undelegate the old view. 
     if (this.child && this.child !== view) this.child.undelegateEvents(); 
     this.child = view; 
     this.child.setElement(this.$el).render(); 
     return this; 
    } 
}); 
+0

Danke viel, Emile! Das hat perfekt funktioniert. Ich denke, ich sollte die Dokumente mehr lesen. Jetzt gibt es ein anderes Problem - wenn ich auf "# create" -Button klicke, wirft es den folgenden Fehler auf: 'backbone.js: 1907 Uncaught Error: Eine" URL "-Eigenschaft oder -Funktion muss angegeben werden, aber das ist für diese Frage nicht relevant – AlexNikolaev94

+1

@ AlexNikolaev94 dieser Fehler hat mit Ihrem 'Resume'-Modell zu tun, das keine 'urlRoot'-Eigenschaft hat oder sich in einer Sammlung befindet, die eine' url'-Eigenschaft hat. –

+0

es existiert genau in einer Sammlung, die eine 'URL'-Eigenschaft hat. Soll ich es entfernen und 'urlRoot' -Eigenschaft zum Modell hinzufügen? – AlexNikolaev94

Verwandte Themen