我们正在将一种中等大小的应用程序从聚合物1迁移到聚合物3.到目前为止,我们仍处于使混合组件工作的中间步骤。
我们正在考虑有关组件初始化时序的一些困难。例如:
<my-app>
<my-component slot='componentslot'><my-component>
</my-app>
似乎有些情况下my-component
在my-app
初始化之前被初始化。它可能会有所不同my-component
是影子或光明的一部分。
我们有很多紧耦合的组件,它们依赖于确定性的初始化顺序。例如,有一个树状结构,其中每个边缘和每个叶子使用事件来发现它在树中的自身深度。因此,我们需要在内部组件之前初始化顶级元素。
但到目前为止我们发现的基本上是:组件的任何初始化顺序都没有garantuee。
是否存在解决此问题的既定模式?聚合物3中是否会解决这个问题(所以我们无论如何都不需要关心它)?
编辑
我被要求提供一些更具体的例子
例1
<my-layout>
<my-complex-component id="1">
<my-reuseable-part/>
</my-complex-component>
<my-complex-component id="2">
<my-reuseable-part/>
</my-complex-component>
<some-other-component>
<my-reuseable-part/>
</some-other-component>
</my-layout>
我有一些可重复使用的组件,需要知道它们是否在my-complex-component
orsome-other-component
中。 my-complex-component
使用context-discovery-behavior
来激活包含回调的事件作为有效载荷。 my-complex-component
和some-other-component
有context-behavior
s听取该事件并通过调用回调来回答它。
但由于my-reusable-part
可能在my-complex-component
或some-other-component
被附加之前附加,这种模式不起作用。
事件听众的注册以及解雇事件都是在attached
(即connectedCallback
)完成的。
例2
<my-tree>
<my-tree-edge>
<my-tree-edge>
<my-leaf/>
<my-tree-edge>
<my-leaf/>
</my-tree-edge>
</my-tree-edge>
<my-tree-edge>
<my-leaf/>
</my-tree-edge>
<my-leaf/>
</my-tree-edge>
</my-tree>
在上面的示例中,每个叶子和边缘都需要知道嵌套的深度。每个元素再次触发一个事件,其父元素将回答该事件。再次在attached
/ connectedCallback
中进行听众注册和事件发放。如果在连接父节点之前连接了内部节点,那么mechanik将再次失败。
希望这可以帮助。
你可以使用dom-if
元素如果你想要确定首先渲染my-app
然后你可以让渲染my-component
像:
<my-app ready="{{myAppReady}}>
<template is='dom-if' if="[[myAppReady]]">
<my-component slot='componentslot'><my-component>
</template>
</my-app>
在我的应用程序脚本:
static get properties(){return {
ready:{type:Boolean,
notify:true,
value:false
}}
在这一部分,你可以添加computed:"checkThisValuesToBeSUre(x,[y]..)
,以确保是否依赖于某些值,或者你可以添加各种条件,以呈现my-component
此外,您可以动态导入my-component.js
,如:
在my-app
的父母脚本:
static get observers(){return ['_checkMyAppReady(myAppReady)']}
_checkMyAppReady(r){
if(r) import('./my-component.js');
}
编辑
如果有很多元素出现同样的问题,那么最好使用lazy-import.js
:
_checkMyAppReady(r){
if(r) import('./lazy-import.js');
}
懒惰import.js
import './my-component.js';
import './my-component2.js';
import './my-component3.js';
...