Javascript 扩展自定义元素在角度2+;
我无法让Angular(2+,而不是AngularJS)很好地处理扩展的自定义元素,它的定义如下:Javascript 扩展自定义元素在角度2+;,javascript,angular,Javascript,Angular,我无法让Angular(2+,而不是AngularJS)很好地处理扩展的自定义元素,它的定义如下: class FancyButton extends HTMLButtonElement { connectedCallback() { this.innerText = `I'm a fancy-button!`; this.style.backgroundColor = 'tomato'; } } customElements.define(
class FancyButton extends HTMLButtonElement {
connectedCallback() {
this.innerText = `I'm a fancy-button!`;
this.style.backgroundColor = 'tomato';
}
}
customElements.define("fancy-button", FancyButton, {
extends: "button"
});
<button is="fancy-button">Fancy button here</button>
这样使用:
class FancyButton extends HTMLButtonElement {
connectedCallback() {
this.innerText = `I'm a fancy-button!`;
this.style.backgroundColor = 'tomato';
}
}
customElements.define("fancy-button", FancyButton, {
extends: "button"
});
<button is="fancy-button">Fancy button here</button>
这里的花式按钮
根据以下Google开发者资源,该定义完全符合web标准:
它在香草web设置和React中工作正常,但Angular忽略了它并显示了一个标准按钮,显然忽略了is=“fancy button”属性
下面是一个演示此操作的示例。
一个奇特的按钮位于角度范围(index.html)之外,工作正常。
另一个按钮位于角度范围(app.component.html)内,不起作用
为什么?为什么?有两种类型的自定义元素:
扩展HtmleElement的类
扩展HTMLButtoneElement
class FancyButtonToo extends HTMLElement {
connectedCallback() {
const buttonElement = document.createElement('button');
this.appendChild(buttonElement);
buttonElement.innerText = "Fancy button #2 here!";
buttonElement.style.backgroundColor = 'tomato';
}
}
customElements.define("fancy-button-too", FancyButtonToo);
(项目还需要模式:[自定义元素\u模式]
已添加。)
至app.module.ts
)。此处的完整代码:,
它的渲染方式如下(原始的“花式按钮”留作比较):
附加信息
问:我们是否确定Angular不能支持定制的内置元素(如
反对,比如说,存在一些我们不知道的模糊配置)
答:我们确信:规范文件
深入讨论自治自定义元素之间的差异
以及定制的内置元素。一个重要的区别在于
元素的程序化构造:
// Built-in Elements and Autonomous Custom Elements are created like this:
el = createElement(name);
// examples
el = createElement("button"); // normal built-in button
el = createElement("fancy-text"); // a custom element
// Customized Built-in Elements are created like this:
el = createElement(built-in-name, { is: custom-built-in-name });
// example
el = createElement("button", { is: "fancy-button" });
相关的角度模板渲染代码位于
对于Angular的当前版本,您将发现:
class DefaultDomRenderer2 implements Renderer2 {
/* ... */
createElement(name: string, namespace?: string): any {
if (namespace) {
return document.createElementNS(NAMESPACE_URIS[namespace] || namespace, name);
}
return document.createElement(name);
}
/* ... */
}
角度渲染器当前没有额外的代码
需要将第二个参数传递到createElement()
;它不能
创建自定义内置元素。
类DefaultDomRender2实现RenderR2{
// ...
创建(名称:字符串、名称空间或选项?:字符串|元素创建选项){
if(名称空间选项和类型名称空间选项==='string'){
//在Ivy(不是ViewEngine)提供实际名称空间的情况下,按键查找
//将导致未定义,因此我们只在此处返回名称空间。
return document.createElements(名称空间URI[名称空间或选项]| |名称空间或选项,名称);
}
if(namespaceorptions&&namespaceorptions.hasOwnProperty('is')){
返回document.createElement(名称、命名空间或选项作为ElementCreationOptions);
}
返回文档.createElement(名称)
}
}
我甚至不会走那条路。。。我们有指令只用于这样的情况:)我明白了。我这样做是为了框架不可知论,我认为“是”按钮“这种方法非常好。在React中工作完美,没有任何React特定代码。我没有在模板中使用标记。它在index.html文件中。不过,我明白你的意思,谢谢你的回答。如果您感兴趣,这个问题与相同的问题有关:您是否考虑过通过此改进向angular存储库发送贡献?您的建议创建(名称:string,namespaceOrOptions?:string | ElementCreationOptions){if(namespaceOrOptions&&typeof namespaceOrOptions==='string'){return document.createElements(NAMESPACE|URIS[namespaceOrOptions]| | namespaceOrOptions,name)}if(namespaceOrOptions&&namespaceOrOptions.hasOwnProperty('is')){return document.createElement(name,namespaceOrOptions as element CreationOptions)}return document.createElement(name)}是不是像约翰·C那样?