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操作的服务。