在Angular 6中扩展本机HTML元素 [英] Extending native HTML element in Angular 6
问题描述
我最近创建了一个本机Web组件,该组件在所有浏览器中均可正常运行.我将此Web组件移至Angular 6应用程序中,所有工作均按预期进行.然后,我尝试扩展本机HTML元素,除了将其引入到Angular 6应用程序中之外,它再次可以正常工作.
I have recently created a native web component which is working well in all browsers. I moved this web component into an Angular 6 application and all works as expected. I then tried to extend a native HTML element which again worked perfectly except when I brought it into my Angular 6 application.
使用Mozilla的示例,我将尝试说明我的问题.使用以下尝试扩展本机'p'元素:
Using the examples from Mozilla I will try and illustrate my issue. Using the following trying to extend a native 'p' element:
// Create a class for the element
class WordCount extends HTMLParagraphElement {
constructor() {
// Always call super first in constructor
super();
// count words in element's parent element
var wcParent = this.parentNode;
function countWords(node){
var text = node.innerText || node.textContent
return text.split(/\s+/g).length;
}
var count = 'Words: ' + countWords(wcParent);
// Create a shadow root
var shadow = this.attachShadow({mode: 'open'});
// Create text node and add word count to it
var text = document.createElement('span');
text.textContent = count;
// Append it to the shadow root
shadow.appendChild(text);
// Update count when element content changes
setInterval(function() {
var count = 'Words: ' + countWords(wcParent);
text.textContent = count;
}, 200)
}
}
// Define the new element
customElements.define('word-count', WordCount, { extends: 'p' });
<p is="word-count">This is some text</p>
通过采用相同的代码并将其放入Angular 6应用程序,该组件将永远不会运行.我将控制台日志语句放在构造函数和connectedCallback方法中,它们从不触发.如果我删除{extends:'p'}对象并更改extends HTMLParagraphElement并将其扩展为HTMLElement作为自主的自定义元素,那么一切工作都会很好.我是在做错什么还是Angular 6不支持自定义的内置元素扩展?
By taking that same code and putting it into an Angular 6 application, the component never runs. I put console log statements in the constructor and connectedCallback methods and they never trigger. If I remove the {extends: 'p'} object and change the extends HTMLParagraphElement and make it an extend HTMLElement to be an autonomous custom element everything works beautifully. Am I doing something wrong or does Angular 6 not support the customized built-in element extension?
推荐答案
我认为原因是Angular在解析组件模板时创建了这些自定义的内置元素的方式-它可能不知道如何正确地做到这一点.奇怪的是,它认为is
是常规属性,可以在创建元素后添加(不是).
I assume the reason is the way that Angular creates those customized built-in elements when parsing component templates - it probably does not know how to properly do that. Odds are it considers is
a regular attribute which is fine to add after creation of the element (which it isn't).
不幸的是,首先创建元素,然后添加is
属性将不升级元素.
First creating the element and then adding the is
-attribute will unfortunately not upgrade the element.
请参见以下示例:div#d
包含该自定义input
的无效示例.
See below example: div#d
has a non-working example of that customized input
.
customElements.define('my-input', class extends HTMLInputElement {
connectedCallback() {
this.value = this.parentNode.id
this.parentNode.classList.add('connected')
}
}, {
extends: 'input'
})
document.addEventListener('DOMContentLoaded', () => {
b.innerHTML = `<input type="text" is="my-input">`
let el = document.createElement('input', {
is: 'my-input'
})
el.type = 'text'
c.appendChild(el)
// will not work:
let el2 = document.createElement('input')
el2.setAttribute('is', 'my-input')
el2.type = 'text'
d.appendChild(el2)
})
div {
border: 3px dotted #999;
padding: 10px;
}
div::before {
content: "#"attr(id)" ";
}
.connected {
background-color: lime;
}
<div id="a"><input type="text" is="my-input"></div>
<div id="b"></div>
<div id="c"></div>
<div id="d"></div>
因此,要使其与Angular一起使用,请进入Angular组件的生命周期(例如onInit()
回调),然后选择一种在此处创建元素的可行方法.
So to get it to work with Angular, hook into the lifecycle of your Angular component (e.g. onInit()
callback) and pick a working way to create your element there.
这篇关于在Angular 6中扩展本机HTML元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!