Расширить пользовательский элемент веб-компонентов v1
У меня есть собственный веб-компонент, <app-list>
что я пытаюсь расширить в <calcs-list>
,
// app-list.html
<script>
window.customElements.define('app-list',
class AppList extends HTMLElement {
constructor() {
super();
}
}
);
</script>
В calcs-list.html я получил:
<link rel="import" href="app-list.html">
<script>
window.customElements.define('calcs-list',
class CalcsList extends AppList {
constructor() {
super();
console.log('CalcsList constructed');
}
}
);
</script>
Однако я получаю ошибку
Uncaught ReferenceError: AppList не определен в calcs-list.html:11
Линия 11 ссылок class CalcsList extends AppList {
Оба файла являются братьями и сестрами одной и той же папки. Я пытался использовать абсолютный путь при импорте app-list.html
в calcs-list.html
но получил тот же результат.
Я также попытался импортировать оба компонента в мой основной файл index.html:
//index.html
<link rel="import" href="/src/components/app-list.html">
<link rel="import" href="/src/components/calcs-list.html">
<app-list></app-list>
<calcs-list></calcs-list>
Но опыт тот же результат.
app-list
Компонент работает в моем приложении без каких-либо проблем.
Я ломаю голову над этим, и поскольку веб-компоненты значительно новы, в Интернете не так много информации об устранении неполадок, особенно с веб-компонентами V1.
Спасибо!
2 ответа
Благодаря @Supersharp я переписал собственное объявление компонента как таковое:
// app-list.html
<script>
class AppList extends HTMLElement { ... }
customElements.define('app-list', AppList);
</script>
А также calcs-list.html
:
<script>
class CalcsList extends AppList { ... }
customElements.define('calcs-list', CalcsList);
</script>
Предупреждение: если вы объявляете тег внутри родительского элемента (расширяемого элемента) с id
тогда это будет конфликтовать с вызовом расширенного элемента super()
,
Например:
<template id="app-list">
...
</template>
Чтобы обойти эту проблему, используйте строковый литерал JavaScript, на который ссылаются разработчики Google, и не используйте id
совсем.
<script>
let template = document.createElement('template');
template.innerHTML = `
<style> ... </style>
<div> ... </div>
`;
class AppList extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({mode: 'open'}).appendChild(template.content.cloneNode(true));
}
}
</script>
Это потому, что когда ты пишешь:
customElements.define('app-list',
class AppList extends HTMLElement {}
);
класс AppList
определяется только в объеме define()
вызов. Вот почему он не виден при последующем использовании во втором файле импорта.
Вместо этого вы должны сначала определить класс (глобально), а затем использовать его в определении пользовательского элемента:
// app-list.html
<script>
class AppList extends HTMLElement {
constructor() {
super();
}
}
window.customElements.define('app-list', AppList);
</script>