Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 主干在每个请求页上创建一个新的视图实例_Javascript_Forms_Backbone.js - Fatal编程技术网

Javascript 主干在每个请求页上创建一个新的视图实例

Javascript 主干在每个请求页上创建一个新的视图实例,javascript,forms,backbone.js,Javascript,Forms,Backbone.js,在我的应用程序中,我创建了一个视图。该视图由一个类似于小表单的模板组成。表单有一个按钮,在我的视图中,我创建了一个click事件来处理这个按钮,以创建另一个视图的新实例,将表单数据传递给这个视图,并将数据放在html元素上。问题是:如果我在主路径或产品中输入3次并发送表单数据,将出现3个相同的表单数据 窗体视图 window.userFormView = Backbone.View.extend({ el:$("#principal"), events : { 'click .u

在我的应用程序中,我创建了一个视图。该视图由一个类似于小表单的模板组成。表单有一个按钮,在我的视图中,我创建了一个click事件来处理这个按钮,以创建另一个视图的新实例,将表单数据传递给这个视图,并将数据放在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.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;
  }
});
最后是用户视图:

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

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

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

index: function () {
    window.users = window.users || new userCollections();
    if(window.userForm){
      // clean up is important
      window.userForm.remove();
    }
    window.userForm  = new userFormView();
},
当然,不要在所有路由中重复类似的代码,而是使用一个类似于this.currentView的变量指向活动视图,并使用一个公共函数进行必要的清理


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

我找到了答案。我实现了单例模式,以仅获取对象的一个实例。请遵循以下代码:

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

现在还不清楚
userviews
做了什么,总的来说,你的问题是对的。我添加了userviews和userviews,这是一个由userviews实例化的视图。它不起作用。表单只出现一次。如果在渲染其他视图后返回,则表单元素不会再次显示。我已经实现了单例模式,它工作得很好。@adahox_uu可能是因为您没有一个模板,其中的元素用于返回时呈现的
el
选项。在这种情况下,您不应该使用
el
选项。应该让主干为每个视图实例创建新的
el
el
应该在创建视图时,当元素在DOM中可用时使用。你所做的不是正确的方法你是说我必须以友好的方式创建模板吗?Remove()方法是否从html中删除该元素?是吗?@adahox_u如果不指定
el
选项,主干将为每个视图实例创建一个DOM元素(您可以使用各种选项对其进行自定义)。您应该将其附加到静态容器元素(即使在不同路由之间切换后仍保留在DOM中的元素)。通常,在创建视图实例(例如作为父模板的一部分)之前,对动态元素使用
el
选项,确保这些元素在DOM中可用。理想情况下,避免使用它,
Backbone
标签下的许多错误都是由它的不正确用法引起的。你真的把这件事复杂化了。TJ给了你正确的答案。理解它将帮助你解决问题。单例模式的存在是有原因的,它不是为了解决这类问题。大多数情况下,您应该避免使用单例模式。即使它是解决方案,这也是一个过度的实现。
       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();