1

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

http://jsbin.com/tunazatu/6/edit?js,控制台,输出

  1. 单击所有视图按钮
  2. 然后点击返回查看1
  3. 单击红色按钮(所有视图的模型 console.log 他们的名字)

因此,我查看了这篇文章中的代码多重事件触发,这表明您可以拥有多个视图,这些视图具有相同的 el thru tagName 但仅将事件映射到它们的 html 元素。这也是 Jérôme Gravel-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();
    }
  });
4

1 回答 1

1

你的问题是你AppView真的看起来像这样:

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

每次创建新的AppView时,都会将另一个事件委托人绑定到,#content但永远不会删除这些委托。如果你创建三个AppViews,你最终会得到三个正在听click buttoninside的视图#content

我会推荐两件事:

  1. 避免尝试重用视图,View#remove根据需要创建和销毁它们(通过 )。视图应该足够轻量级,以便将它们放在一起并拆除它们应该很便宜。
  2. 不要将多个视图绑定到同一个el. 相反,让每个视图创建自己的视图el,然后让调用者将其el 放入某个容器中。

如果你同时做这两件事,那么你的问题就会消失。你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 ----------^^
},

如果您必须坚持当前的方法,那么您必须在渲染另一个方法之前调用当前方法,并undelegateEvents在渲染它之后调用新方法。AppViewdelegateEventsAppView

但实际上,不要害怕立即销毁您不需要的视图:销毁页面上您现在不需要的任何视图,并在需要时创建新实例。在某些情况下,您不想破坏您的视图,但通常可以避免它。

于 2014-05-20T05:05:57.567 回答