我试图弄清楚为什么Ember组件不起作用(并试图了解过程中的组件生命周期)。有问题的组件是Ember-cli-mapbox。它使用嵌套组件。您可以拥有mapbox-map
组件,在该组件中,您可以拥有多个mapbox-marker
组件。现在,它应该如何工作,mapbox-map
组件初始化地图,然后将块传递给子标记组件。子标记组件然后引用传递给它们的映射。正在使用的组件示例(来自组件文档):
{{#mapbox-map mapId='ember-cli-mapbox.7c3914f2' as |map|}}
{{#each positions as |position|}}
{{mapbox-marker map=map coordinates=position.coordinates}}
{{/each}}
{{/mapbox-map}}
现在,使用didInsertElement
钩子设置组件,这对我来说很有意义,因为在mapbox-map
组件可以绑定到dom中的元素之前,DOM需要到位。虽然它不像那样工作。子组件的didInsertElement
在父组件中的didInsertElement
挂钩之前执行。因此,标记会在创建之前尝试引用地图。我通过将console.log
s放在组件初始化代码中来解决这个问题。我找不到很多关于组件生命周期的文档。 API文档here中引用了didInsertElement
,但似乎最新的API文档实际上已过时,并且未引用一堆描述为here的其他挂钩。后一个链接表示生命周期事件按以下顺序发生:
didInitAttrs
didReceiveAttrs
willRender
didInsertElement
didRender
现在,事情变得奇怪了。当我用didInsertElement
替换组件中的didInitAttrs
时,它会以正确的顺序触发。父组件上的didInitAttrs
挂钩首先触发,然后是子组件didInitAttrs
挂钩。问题是,DOM还没有准备好,所以它没有多大帮助。我也不能将地图绑定事件放在Ember runloop中,因为它需要返回并作为块传递给子元素。
所以,我的问题是:
didInsertElement
时,钩子会按照它们的顺序执行吗? (孩子,然后是父母)我在Ember Twiddle here中重新创建了插件。子钩子在父钩子之前被调用,导致组件断开,因为在调用钩子时map
未定义。这发生在Ember 1.13.8以及1.13.9。
答案 0 :(得分:4)
为什么在组件上使用didInsertElement时,请执行钩子get 按照他们的顺序执行? (孩子,然后是父母)
1.8版本已更改。它是以前的父母,然后是孩子,但这通常要求人们使用一些复杂的方法等待孩子渲染来做某些事情。改变顺序使学习Ember更简单。
有关详细信息,请参阅https://github.com/emberjs/ember.js/issues/5631。
这个组件是如何以当前编写的方式工作的?
我没有使用过此插件,也不知道它是否有效。然而,我修复了你的工作:http://ember-twiddle.com/4c3e55d0a66ead378bdf
如果他们不是,我应该使用上面提到的钩子 官方API文档中提到了什么?
没有提到这些钩子,因为文档仍在追赶Ember的变化。如果您愿意,请随意使用它们。