【发布时间】:2016-01-09 18:06:50
【问题描述】:
我正在尝试找出 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.logs 放在组件初始化代码中来解决这个问题。我找不到太多关于组件生命周期的文档。 didInsertElement 确实在 API 文档 here 中得到了引用,但似乎最新的 API 文档实际上已经过时,并且没有引用描述 here 的一堆其他钩子。后一个链接表示生命周期事件按以下顺序发生:
didInitAttrs
didReceiveAttrs
willRender
didInsertElement
didRender
现在,事情变得很奇怪。当我用didInitAttrs 替换组件中的didInsertElement 时,它会以正确的顺序触发。父组件上的didInitAttrs 挂钩首先触发,然后是子组件didInitAttrs 挂钩。问题是,DOM 还没有准备好,所以它没有多大帮助。我也不能将地图绑定事件放在 Ember 运行循环中,因为它需要返回并作为块传递给子元素。
所以,我的问题是:
- 为什么,在组件上使用
didInsertElement时,钩子会按照它们的执行顺序执行吗? (孩子,然后是父母) - 这个组件是如何按照目前的编写方式工作的?
- 如果官方 API 文档中未提及上述钩子,我是否应该使用它们?
我在Ember Twiddle here 中重新创建了插件。子挂钩在父挂钩之前被调用,导致组件中断,因为在调用挂钩时 map 未定义。这发生在 Ember 1.13.8 和 1.13.9 上。
【问题讨论】:
标签: ember.js