Angular Elements,四步将Angular 组件转换为 web 组件
从Angular版本6开始,我们可以将Angular组件公开为Web组件,或者更确切地说:作为自定义元素,它是Web组件这一术语的标准之一。它们可以在每个框架中重复使用,甚至可以与原生JS一起使用。除此之外,我们可以在运行时轻松创建它们,因为它们是由浏览器呈现的。动态添加新的DOM节点。
在这里,我正在使用这个想法来构建动态dashboard。
该源代码可以在这里查看。
第1步: 安装 Angular Elements 和 Polyfills
毫无疑问,Angular Elements可以通过npm安装。除此之外,我还安装@webcomponents/custom-elements这个polyfills Custom Elements 可以支持Internet Explorer 11。
npm i @angular/elements --save
npm i @webcomponents/custom-elements --save
在此之后,您还可以在结尾处参考polyfill polyfills.ts:
import '@webcomponents/custom-elements/custom-elements.min';
需要在您的引用中引用此包的另一个文件angular.json:
"scripts": [
"node_modules/@webcomponents/custom-elements/src/native-shim.js"
]
Web组件是在EcmaScript 2015+定义的。
作为替代方案,您可以安装@angular/elements,使用ng add命令:
ng add @angular/elements
此命令也会下载polyfill并在其中引用它angular.json。
第2步:创建Angular组件
dashboard 的Angular 组件代码,我希望将其视为Web组件,如下所示:
@Component({
// selector: 'app-dashboard-tile',
templateUrl: './dashboard-tile.component.html',
styleUrls: ['./dashboard-tile.component.css']
})
export class DashboardTileComponent {
@Input() a: number;
@Input() b: number;
@Input() c: number;
}
我没有使用选择器,因为Custom项目在注册时会分配一个。这样,我防止命名冲突。
第3步:将Angular 组件注册为自定义元素
为了将Angular 组件公开为自定义元素,我们需要声明它并将其放在entryComponents模块的部分中。这是必要的,因为Angular Elements在运行时动态创建它:
@NgModule({
[…],
declarations: [
[…]
DashboardTileComponent
],
entryComponents: [
DashboardTileComponent
]
})
export class DashboardModule {
constructor(private injector: Injector) {
const tileCE = createCustomElement(DashboardTileComponent, { injector: this.injector });
customElements.define('dashboard-tile', tileCE);
}
}
方法createCustomElement包装DashboardTileComponent它看起来像Web组件的方式。使用customElements.define我们可以在浏览器中注册它。
第4步:使用自定义元素
现在,我们可以像所有其他内置HTML标记一样使用自定义元素:
<dashboard-tile a="100" b="50" c="25"></dashboard-tile>
当浏览器呈现它时,Angular不知道元素名称dashboard-tile。为了防止它抛出错误,我们必须使用CUSTOM_ELEMENTS_SCHEMA:
@NgModule({
[…]
schemas: [
CUSTOM_ELEMENTS_SCHEMA
]
})
export class AppModule {
}
我们甚至可以动态创建一个DOM节点,它是动态UI的一个关键:
const tile = document.createElement('dashboard-tile');
tile.setAttribute('class', 'col-lg-4 col-md-3 col-sm-2');
tile.setAttribute('a', '100');
tile.setAttribute('b', '50');
tile.setAttribute('c', '25');
const content = document.getElementById('content');
content.appendChild(tile);
如果你想确保你的应用程序也支持其他环境 - 例如服务器端渲染或混合应用程序 - 你应该使用抽象DOM操作的服务。