7

我有一个Marionette.CollectionView呈现ItemViews 的列表。在此期间render(),我使用 ItemViewmodel使用Raphael绘制一些 SVG 。

Raphael 要求我为其画布指定高度和宽度,我通常会从this.$el. 但是,$el(作为空的<div>)在添加到 DOM 并对其应用 CSS 规则之前没有尺寸,所以我需要延迟渲染,直到我知道视图在 DOM 中。

问题是Marionette.CollectionView在渲染之前不会将子视图添加到 DOM。如何在不重新实现一半的情况下覆盖此行为CollectionView

示例代码

// Renders a single object.
var ItemView = Marionette.ItemView.extend({
    template: "#item-view-template",
    onRender: function() {
        var svgEl = this.$el.find("div.svg-canvas");
        // Raphael needs the element's width and height, which
        // is 0 until this.$el is in the DOM.
        var paper = Raphael(svgEl.get(0), svgEl.height(), svgEl.width());
        // ... draw some SVG...
    }
});

// Renders a collection of objects.
var ListView = Marionette.CollectionView.extend({
    itemView: ItemView,
    model: MyModel
});

// Main point of entry.
MyApp.show = function() {
    var collection = new MyCollection();
    var listView = new ListView({ collection: collection });
    MyApp.mainRegion.show(listView);
    collection.fetch();
};
4

1 回答 1

10

onRender不会满足您的需求,因为在呈现视图时会调用此方法 - 但不保证视图已添加到 DOM 中。

为此,您需要一个onShow方法,当您在区域中显示视图时,该方法将由该区域调用。问题是当前的实现只调用onShow你直接传入的视图——在这种情况下是集合视图。因此,您需要以一种使其在所有集合视图的子视图上调用该方法的方式来实现您的 onShow。


Marionette.CollectionView.extend({
  // ...  

  onShow: function(){
    _.each(this.children, function(childView){
      if (childView.onShow){ childView.onShow(); }
    });
  }
});

那应该这样做。当您调用MyApp.mainRegion.show(listView)它时,它将调用onShow集合视图的方法,然后它将在子级上调用它(如果它在那里)。


根据评论中的讨论,即使在调用父视图并且稍后将项目添加到集合中之后,也会调用保证onShow子视图方法的实现:onShow


ItemView = Marionette.ItemView.extend({
  // ...

  onShow: function(){
    // I am guaranteed to be called from the CollectionView
    // because the CollectionView registers me in a promise
  }
});

CollectionView = Marionette.CollectionView.extend({

  initialize: function(){
    this.onShowCallbacks = new Marionette.Callbacks();
  },

  onShow: function(){
    this.onShowCallbacks.run();
  },

  appendHtml: function(cv, iv){
    cv.append(iv.el);

    // promise to run 'onShow' if it exists
    if (iv.hasOwnProperty("onShow")){
      this.onShowCallbacks.add(iv.onShow);
    }
  }
});

也可在此要点中找到:https ://gist.github.com/2872526

于 2012-06-04T23:00:25.293 回答