Backbone在每个请求页面创建一个新的视图实例

时间:2017-03-09 20:29:38

标签: javascript forms backbone.js

在我的应用中,我创建了一个视图。此视图由一个像一个小表格的模板组成。 Form有一个按钮,在我的View中我创建了一个click事件来处理这个按钮来创建另一个View的新实例,将一个Form数据传递给这个View并将数据放在html元素上。问题是:如果我进入家乡路线或产品3次并发送表格数据,将出现3个相同的表格数据。

表单视图

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);
  }
});

表单模板视图

     <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>

我的路线是这样的:

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视图

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;
  }
});

最后是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;
  }
});

2 个答案:

答案 0 :(得分:1)

当您的视图使用el选项时,请确保在创建新视图之前清理现有视图。

实际上,每次在路由之间切换(没有完整页面刷新)时,都会创建一个指向同一元素的新实例,这会导致越来越多的事件处理程序绑定到el元素。 DOM,由于绑定,视图保留在内存中。尝试类似:

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

当然,不是在所有路由中重复使用类似的代码,而是使用指向活动视图的this.currentView变量,以及需要清理的常用函数

P.S:向窗口对象添加属性是一种不好的做法。创建自己的名称空间或使用路由器实例而不是窗口

答案 1 :(得分:-2)

我找到了答案。我实现了单例模式只获取对象的一个​​实例。按照代码:

       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();