2017-03-09 2 views
0

In meiner App habe ich eine Ansicht erstellt. Diese Ansicht besteht aus einer Vorlage wie eine kleine Form. Das Formular hat eine Schaltfläche und in meiner Ansicht erstelle ich ein click -Ereignis, um diese Schaltfläche zu bearbeiten, um eine neue Instanz einer anderen Ansicht zu erstellen, die die Formulardaten an diese Ansicht übergibt und die Daten in das html-Element schreibt. Das Problem ist: wenn ich 3 mal in die Home Route oder in das Produkt eingebe und ein Formular sende, dann erscheinen 3 gleiche Formular Daten.Backbone erstellen eine neue Ansicht Instanz jeder Anfrage Seite

Formularansicht

window.userFormView = Backbone.View.extend({ 
    el:$("#principal"), 
    events : { 
    'click .userButton' : 'newUser' 
}, 
initialize:function(){ 
    this.template = _.template($("#userFormView").html()); 
}, 
newUser : function(ev) { 
    ev.preventDefault(); 
    //criamos uma nova instancia do model 
    window.user_view = new userViewes({model: users}); 
    var u = { nome : $("#iName").val() ,sobrenome : $("#iLName").val() }; 
    var user = new userModel(u); 
    users.add(user); 
    console.log(users); 
    return false; 
}, 
    render: function() { 
    this.$el.html(""); 
    this.$el.html(this.template); 
    } 
}); 

Formularvorlage anzeigen

 <script type="text/template" id="userFormView"> 
     <form action="" id="form-new-user" class="formulario"> 
      <span class="label">Name?</span><input type="text" id="iName" class="input"> 
      <span class="label">Last Name?</span><input type="text" id="iLName" class="input"> 

      <button class="userButton">Send</button> 
      <hr> 

     </form> 
     </script> 

und meine Strecke wie diese sind:

window.AppRouter = Backbone.Router.extend({ 

// 
// Definindo rotas 
// 
routes: { 
    'home':  'index', 
    'product': 'productsList', 
    'foo1': 'doNothing1', 
    'foo2': 'doNothing2' 
}, 

index: function() { 

     window.users = new userCollections(); 
     window.userForm = new userFormView(); 
}, 
productsList : function() { 

    window.pCollection = new productCollections(); 
    window.produtoForm = new produtoFormView(); 
}, 
doNothing1: function() { 
    console.log('doNothing1()'); 
}, 
doNothing2: function() { 
    console.log('doNothing2()'); 
} 
}); 
window.router = new AppRouter(); 
Backbone.history.start(); 

userViewes sehen

window.userViewes = Backbone.View.extend({ 
    // model: users, 
    el: $("#userContainer"), 
    initialize: function(){ 
    this.model.on("add", this.render, this); 
    this.model.on("remove", this.render, this); 
    }, 
    render: function() { 
    var self = this; 
    self.$el.html(""); 
    this.model.each(function(user, indice) { 
     self.$el.append((new userView({model: user })).render().$el); 
    }); 
    return this; 
    } 
}); 

und schließlich userview:

window.userView = Backbone.View.extend({ 
    //model: new userModel(), 
    tagName : 'div', 
    class : "userName", 
    events :{ 
    'click .editar' : 'editar', 
    'click .remover' : 'remover', 
    'blur .sobrenome': 'fechar', 
    'keypress .sobrenome' : 'onEnterUpdate', 
    }, 
    editar : function(ev) { 
    ev.preventDefault(); 
    this.$('.sobrenome').attr('contenteditable', true).focus(); 
    }, 
    fechar : function(ev) { 
     var sobrenome = $(".sobrenome").text(); 
     this.model.set("sobrenome", sobrenome); 
     $(".sobrenome").val(); 
     this.$(".sobrenome").removeAttr("contenteditable"); 
    }, 
    onEnterUpdate : function(ev) { 
    var self = this; 
    if(ev.keyCode == 13) { 
     self.fechar(); 
     _.delay(function(){ 
     self.$(".sobrenome").blur(); 
     }, 100); 
    } 
    }, 
    remover : function(ev) { 
    ev.preventDefault(); 
    window.users.remove(this.model); 
    }, 
    initialize: function(){ 
    this.template = _.template($("#userTemplate").html()); 
    }, 
    render : function() { 
     this.$el.html(this.template(this.model.toJSON())); 
     return this; 
    } 
}); 
+0

Es ist nicht klar, was 'userViewes' tut, und im Allgemeinen Ihre Frage –

+0

Sie haben Recht. Ich habe userViewes und auch userViewes hinzugefügt, eine Ansicht, die von userViewes erstellt wurde. –

Antwort

1

Wenn Ihre Ansicht el Option verwenden, stellen Sie sicher, reinigen Sie die vorhandene Ansicht, bevor Sie eine neue zu machen.

Jedes Mal, wenn Sie zwischen den Routen wechseln (ohne vollständige Seitenaktualisierung), wird eine neue Instanz erstellt, die auf dasselbe Element verweist. Dadurch werden mehr und mehr Ereignishandler an das Element el gebunden Die Ansichten bleiben wegen der Bindung im Gedächtnis. Versuchen Sie so etwas wie:

index: function() { 
    window.users = window.users || new userCollections(); 
    if(window.userForm){ 
     // clean up is important 
     window.userForm.remove(); 
    } 
    window.userForm = new userFormView(); 
}, 

Und natürlich statt in allen Routen ähnlichen Code zu wiederholen, hat eine Variable wie this.currentView, die auf die aktive Ansicht zeigt, und eine gemeinsame Funktion, die notwendig macht aufzuräumen

PS : Das Hinzufügen von Eigenschaften zu einem Fensterobjekt ist eine schlechte Übung. Erstellen Sie Ihren eigenen Namensraum oder verwenden Sie die Router-Instanz anstelle des Fensters

+0

es funktioniert nicht. Das Formular erscheint nur einmal. Wenn ich nach dem Rendern anderer Ansicht zurücktrete, wird das Formularelement nicht erneut angezeigt. Ich habe Singleton-Muster implementiert und es funktioniert gut. –

+0

@adahox_ Wahrscheinlich, weil Sie keine Vorlage mit dem Element haben, das für 'el' Option verwendet wird, die gerendert wird, wenn Sie zurückgehen. In diesem Fall sollten Sie die Option "el" nicht verwenden. Sie sollten das Backbone für jede View-Instanz ein neues 'el' erstellen lassen. –

+0

'el' sollte verwendet werden, wenn das Element in DOM verfügbar ist, wenn Sie die Ansicht erstellen. Was du machst ist nicht der richtige Weg –

-2

Ich habe die Antwort gefunden. Ich habe ein Singleton-Muster implementiert, um nur eine Instanz des Objekts zu erhalten. folgen Sie dem Code:

 var single = (function(){ 
     function createInstance() { 
      window.userForm = new userFormView(); 
      window.users  = new userCollections(); 
     } 

     function users() { 
      return window.users; 
     } 

     function userForm() { 
      return window.userForm; 
     } 

     return { 
      init : function() { 
       if(!window.users && !window.userForm) { 
        createInstance(); 
       }else{ 
        this.render(); 
       }    
      }, 

      render: function() { 
       window.userForm.render(); 
      } 

     } 
    }()); 

    single.init(); 
+0

Sie verkomplizieren das wirklich. –

+0

warum? es funktioniert:/ –

+0

TJ gab Ihnen die richtige Antwort. Das Verständnis wird Ihnen helfen, das Problem zu lösen. Das Singleton-Muster existiert aus einem bestimmten Grund und es ist nicht die Lösung für diese Art von Problem. Die meiste Zeit sollten Sie das Singleton-Muster vermeiden. Und selbst wenn es die Lösung wäre, ist dies eine Overkill-Implementierung. –

Verwandte Themen