backbone js view仅绑定视图元素的事件

时间:2014-05-20 03:43:26

标签: backbone.js backbone-views event-binding

您好我正在学习骨干,我遇到了将事件绑定到视图的问题。我的问题是我有一个视图构造函数,在调用时,将所有视图绑定到按钮按下事件,该事件只是一个视图的一部分。我希望按钮按下事件仅绑定到包含按钮的1个视图。

http://jsbin.com/tunazatu/6/edit?js,console,output

  1. 点击所有视图按钮
  2. 然后点击返回查看1
  3. 单击红色按钮(所有视图的模型console.log名称)
  4. 所以我查看了这篇文章mutliple event firing中的代码,该代码显示您可以拥有多个具有相同el thru tagName但仅将事件映射到其html元素的视图。这也是JérômeGravel-Niquet

    的localtodos示例中所做的

    我也试过不声明el / tunazatu / 7 / edit?js,console,output但是看起来似乎没有事件被绑定。

    
        var AppView = Backbone.View.extend({
        tagName:"div",  //tagName defined
        getName:function(){
          console.log(this.model.get('name'));
        },
        initialize:function(options){
          this.listenTo(this.model, 'change', this.render);
          var temp_mapper = {appView1:'#route1',appView2:'#route2',appView3:'#route3'};
          var m_name = this.model.get('name');
          this.template = _.template($(temp_mapper[m_name]).html());  //choose the correct template
        },
        render:function(){
          var temp = this.template(this.model.toJSON()); //populate the template with model data
          var newElement = this.$el.html(temp);  //put it in the view's tagName
          $('#content').html(newElement);
        },
        events:{
          "click button":"log"
        },
        log:function(){
          this.getName();
        }
      });
    

1 个答案:

答案 0 :(得分:1)

您的问题是您的AppView看起来真的如此:

var AppView = Backbone.View.extend({
    el: "#content",
    //...

每次创建新的AppView时,都会将另一个事件委托者绑定到#content,但您永远不会删除这些委托。如果您创建了三个AppView,则最终会在click button内听到三个观看#content的观看次数。

我会推荐两件事:

  1. 根据需要,避免尝试重新使用视图,创建和销毁视图(通过View#remove)。视图应该足够轻巧,将它们放在一起并将它们撕下来应该很便宜。
  2. 不要将多个视图绑定到同一个el。相反,让每个视图创建自己的el,然后让调用者将el 放在某个容器中。
  3. 如果你同时做这两件事,你的问题就会消失。您的AppView看起来更像是这样:

    var AppView = Backbone.View.extend({
      render: function() {
        this.$el.html(this.template(this.model.toJSON()));
        return this; // Common practise, you'll see why shortly.
      },
      // As you already have things...
    });
    

    然后你的路由器方法看起来更像这样:

    view1: function() {
      if(this.appView)
          this.appView.remove();
      this.appView = this.createView('appView1');
      $('#content').html(this.appView.render().el);
      // that `return this` is handy ----------^^
    },
    

    如果您必须坚持使用当前的方法,那么您必须在当前AppView上调用undelegateEvents,然后再渲染另一个delegateEventsAppView在渲染之后。

    但实际上,不要害怕破坏你此刻不需要的观点:破坏你现在不需要的任何视图,并在当时创建新的实例你需要它们。在某些情况下,您不想破坏您的观点,但通常可以避免它。