Backbone.js 如何在CollectionView中呈现依赖DOM的视图?

Backbone.js 如何在CollectionView中呈现依赖DOM的视图?,backbone.js,marionette,Backbone.js,Marionette,我有一个木偶.CollectionView,它呈现项目视图的列表。在render() Raphael要求我为它的画布指定一个高度和宽度,这通常是我从这里获取的。$el。但是,$el(作为一个空的)在添加到DOM并应用CSS规则之前没有维度,因此我需要延迟渲染,直到知道视图在DOM中 问题是,Marionette.CollectionView在呈现子视图之前不会将其添加到DOM中。如何在不重新实现一半的CollectionView的情况下重写此行为 示例代码 onRender无法满足您的需要,因为

我有一个
木偶.CollectionView
,它呈现
项目视图的列表。在
render()

Raphael要求我为它的画布指定一个高度和宽度,这通常是我从
这里获取的。$el
。但是,
$el
(作为一个空的
)在添加到DOM并应用CSS规则之前没有维度,因此我需要延迟渲染,直到知道视图在DOM中

问题是,
Marionette.CollectionView
在呈现子视图之前不会将其添加到DOM中。如何在不重新实现一半的
CollectionView
的情况下重写此行为

示例代码
onRender
无法满足您的需要,因为在渲染视图时会调用此方法,但不能保证视图已添加到DOM中

为此,您需要一个
onShow
方法,当您在区域中显示视图时,该区域将调用该方法。问题在于,当前实现只在您直接传入的视图上调用
onShow
——在本例中是collection视图。因此,您需要实现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);
    }
  }
});

也可在此要点中找到:

我想到了这一点,但我将在
onShow
中使用该模型。将
CollectionView
添加到区域时,仍在提取集合。我需要一个“render,除非您还不在DOM中,在这种情况下,请等到您在继续之前”方法。也许我应该等到初始获取完成后,再将我的CollectionView添加到区域中……啊,所以您需要承诺子视图的onshow方法。“我保证子视图的onshow方法将被调用,即使在父视图被渲染后调用子视图也是如此”。我可以为你准备。啊,我没想到!回答得很好,再次感谢您的帮助。:)是否应该将
cv.append
设置为
cv.el.append
?我正在努力解决一些非常类似的问题,只是我正在传递itemView选项中的显示,并尝试获取每个itemView的$el的高度。但是,如果我严格遵循这一点,则高度始终为0。

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