问题空间
我正在渲染一些嵌套的 Ember 视图,这样我就可以制作一个拆分窗格样式的 UI。我想在第一次渲染时调整我的视图大小,以便它们具有相等的宽度。我不希望我的子视图互相看着,所以我使用一个子类Ember.ContainerView
来保存我的内容和可拖动的拆分器句柄。
我不能Ember.View#didInsertElement
在我的容器视图上使用,因为我需要等待我的子视图完全呈现。
我的(尝试的)解决方案
我正在使用此答案中提供的代码:如何等待模板完全呈现。这会isRendered
为所有实例添加一个属性,该属性会在模板通过重新打开 Ember.ViewEmber.View
触发时自动设置:didInsertElement
Ember.View.reopen
didInsertElement: ->
res = @_super();
@_setIsRendered();
res
_setIsRendered: ->
if (!! @$())
@set('isRendered', true)
else
Ember.run.next this, ->
@_setIsRendered()
我尝试重新打开Ember.ContainerView
以向所有容器视图添加一个childViewsRendered
属性,但 Ember 反对并为子视图中只有一个项目的容器视图抛出了一些非常奇怪的 IndexOutOfBounds 错误。
我最终将我的收藏代码放在以下 mixin 中:
App.ChildrenRendered = Ember.Mixin.create
childViewsRendered: (->
res = @get('childViews').everyProperty('isRendered')
console.log('childViewsRendered', res, this)
# Pointer to this most offensive object for debugging
window.wtf = this
res
).property('childViews.@each.isRendered')
_runChildViewsDidRender: (->
if @get('childViewsRendered')
console.log('trying to invoke childViewsDidRender')
Ember.tryInvoke(this, 'childViewsDidRender')
).observes('childViewsRendered')
然后我有这样的课:
App.SplitterView = Ember.ContainerView.extend App.ChildrenRendered,
# ...(some properties)...
init: ->
child_views = @get('childViews')
child_views.pushObjects([App.WindowView.create(), App.WindowView.create()])
什么有效:
App.SplitterView#childViewsRendered
在任何视图渲染之前计算一次,因此变为false
- 视图由 Ember 处理(插入和渲染),并设置它们自己的
isRendered
属性。 - 稍后运行
window.wtf.get('childViews').everyProperty('isRendered')
返回true
。
什么不起作用:
- 计算的属性
childViewsRendered
永远不会再自我更新。 - 数组元素成员上的虚拟值的计算属性
childView
似乎也不起作用。