【问题标题】:Backbone Event of Subview not firing correctly子视图的主干事件未正确触发
【发布时间】:2012-10-31 09:41:36
【问题描述】:

我在 Backbone 中有一个由 GalleryItem 子视图组成的画廊。

我现在遇到的问题是子视图上的事件没有正确触发。

这是我GalleryItemView的代码:

// Gallery View: Displays a Single Image Element
var GalleryItemView = Backbone.View.extend({
  el: '#isotope',

  events: {
    "click .hoverbox": "onHoverBoxClick"
  },


  initialize: function () {
    this.template = Hogan.compile($("#gallery-item-template").html());
  },

  render: function () {
    this.$el.append(this.template.render(this.model.toJSON())); 
    return this;
  },
  onHoverBoxClick: function () {
    console.log("clicked: ", this.model.id);
  }

});

我希望每个元素在单击 .hoverbox div 时都会触发 onHoverBoxClick 事件。 但它什么也没做。 如果我将此添加到视图中:

el: "#mydiv"

然后它会触发事件,但会针对每个 GalleryItemView。 (所以对于 8 个子视图,我得到 8 个 console.logs,我也只点击了一个)

我的子视图模板如下所示:

<script type="text/x-handlebars-template" id="gallery-item-template">
  <div class="item {{tags}}" style="width: auto;">
    <img class="eveimage" src="{{image_medium_url}}">
    <div class="hoverbox down"><span>{{tags}}</span>    </div>
</div>
</script>

画廊的收藏视图看起来像这样(这是我实例化画廊项目的地方):

// Gallery View: Displays the main image / project gallery
window.views.GalleryView = Backbone.View.extend({
  el: '#isotope_container',
  className: 'no-transition',
  template: _.template($("#gallery-template").html()),

  initialize: function() {
    this.collection = new gallery();
    this.$el.append(this.template);
    this.collection.on('reset', this.render, this);
  },

  render: function(){  
    console.log("ich render nei");
    this.collection.forEach(this.addOne, this);  

  },  
  addOne: function(model){  
    var itemView = new GalleryItemView({model: model});
    var el = itemView.render().el;

    this.$el.append(el);  
  }
});

任何想法为什么会这样?谢谢...

【问题讨论】:

  • 我没有看到你的模板,但假设它是视图列表,所以每个li 都有不同的 id 属性。然后调用视图:new GalleryItemView({model: model, el: '#gallery-item-id'}) 与项目的 id 将委托绑定到这个特定元素
  • 感谢 Eru,但这并没有什么不同。据我了解,为了触发事件,实际上没有必要有一个“el”或一个特定的 id。
  • 你需要 el 才能让主干绑定事件

标签: javascript backbone.js backbone-views backbone-events


【解决方案1】:

当您在 Backbone 视图上指定 events 哈希时,Backbone 使用 jQuery .delegate 方法绑定回调,并以视图的 el 作为根元素。但是,在您的 GalleryItemView.render 方法中,您实际上并没有渲染到视图的 el;您正在选择一个完全不同的元素。因此,事件实际上是在您的事件哈希范围之外触发​​的。

相反,你需要做这样的事情

window.views.GalleryItemView = Backbone.View.extend({
   ...
  render:function () {
    this.$el.append(this.template.render(this.model.toJSON())); 
    return this;
  }, 
  ...
});

查看您当前的代码,您在 GalleryView 上定义的渲染方法只是附加了一堆空的&lt;div&gt; 标签。您正在选择页面上的现有元素并在 GalleryViewItem.render 方法中附加您的插值模板这一事实实际上是导致您的项目出现的原因。

[[第 2 部分]] 在您编辑的视图中,您提供了一个 ID 选择器作为 GalleryItemView 上的 el 属性。正因为如此,加上您使用.append() 呈现每个项目视图的方式,您仍然将每个GalleryItemView 实例附加到同一个元素。由于它们都共享相同的根元素,因此当委托事件时,一个事件将导致每个 GalleryItemView 的处理程序被调用。

您应该拥有如下内容:

GalleryItemView = Backbone.View.extend({
  // remove the ID selector for the el property -- don't need it
  ...
  render:function() {
    this.$el.html(this.template.render(this.model.toJSON()));
    return this;
  }
  ...
});

window.views.GalleryView = Backbone.View.extend({
  ...
  addOne: function(model){  
    var itemView = new GalleryItemView({model: model});
    var el = itemView.render().el;

    // assuming you actually intended to attach all 
    // GalleryItemViews to the #isotope element
    this.$('#isotope').append(el);  
  }
  ...
});

【讨论】:

  • 你是对的。但我之前有一个“el”,它也不起作用。我用“el”将问题编辑为版本 - 至少现在 exmpty div 已经消失了;)
猜你喜欢
  • 1970-01-01
  • 2012-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多