Порядок инициализации компонентов в полимере 2 - PullRequest
1 голос
/ 01 апреля 2019

Мы переносим приложение среднего размера с полимера 1 на полимер 3. До сих пор мы застряли на промежуточном этапе приведения в действие наших гибридных компонентов.

Мы сталкиваемся с некоторыми трудностями в отношении времени инициализации компонента.Например:

<my-app>
  <my-component slot='componentslot'><my-component>
</my-app>

Кажется, есть случаи, когда my-component инициализируется до инициализации my-app.Это может варьироваться, если my-component является частью тени или света.

У нас есть много тесно связанных компонентов, которые зависят от детерминированного порядка инициализации.Например, существует древовидная структура, где каждый край и каждый лист используют события, чтобы обнаружить свою собственную глубину в дереве.Поэтому нам нужно, чтобы элементы верхнего уровня были инициализированы перед внутренними компонентами.

Но то, что мы до сих пор обнаружили, было по существу: нет гарантии для какого-либо порядка инициализации компонентов.

Существует ли установленная схема решения этой проблемы?Будет ли эта проблема решена в полимере 3 (так что нам все равно об этом не нужно заботиться)?

Edit

Меня попросили привести более конкретные примеры

Пример 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 или some-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 присоединено, этот шаблон не работает.

Регистрация прослушивателей событий, а также запуск события disovering завершеныв 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.Опять же, механик выходит из строя, если внутренний узел присоединен до того, как присоединены его родители.

Надеюсь, это поможет.

1 Ответ

0 голосов
/ 02 апреля 2019

Вы можете использовать элемент 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>

в сценарии 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');
}

lazy-import.js

import './my-component.js';
import './my-component2.js';
import './my-component3.js';
...
...