代码之家  ›  专栏  ›  技术社区  ›  Nelladel

在Angular中导入与渲染自定义Web组件

  •  1
  • Nelladel  · 技术社区  · 8 月前

    我们正在构建一个原生JS web组件库(Foo web Components,或FWC),并试图在Angular应用程序中使用它(目前没有包装器)。

    • 我们将其打包为NPM包,并通过以下方式将其作为依赖项安装 npm i @foo/foo-web-components .
    • 我们正在一个模块中导入一个全新的Angular 18应用程序中的必要组件。
    • 我们试图在一个简单的程序中使用两个组件(Input和Datepicker) app.component .

    我们的相关文件现在如下:

    app.component.ts :

    import { Component, CUSTOM_ELEMENTS_SCHEMA, ElementRef, ViewChild } from '@angular/core';
    
    import { FWCInput, FWCDatepicker } from '@foo/foo-web-components';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      templateUrl: './app.component.html',
      styleUrl: './app.component.css',
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
    export class AppComponent {
      public today: Date = new Date();
      //@ts-ignore
      @ViewChild("datepicker") datepicker: ElementRef<FWCDatepicker>;
      //@ts-ignore
      @ViewChild("input") input: ElementRef<FWCInput>;
    
      constructor() { }
    
      ngAfterViewInit(): void {
        console.log(this.datepicker);
        console.log(this.input);
      }
    }
    

    app.component.html :

    Datepicker: <fwc-datepicker #datepicker [date]="today" label="Datepicker"></fwc-datepicker>
    Input: <fwc-input #input placeholder="placeholder" value="From Template" label="Input"></fwc-input>
    

    使用此配置,页面看起来像这样: not-working 控制台或构建过程中没有错误,但组件不在DOM中或未呈现。

    但是,如果我们在构造函数中添加一行 app.component.ts 因此:

      constructor() {
        var foo = new FWCInput();
      }
    

    突然,组件出现了: working

    我假设这与Angular实际加载导入的时间有关。。。如果它“没有实际使用”(正如框架所认为的那样),它就不会加载它。 但是,当我们仅从库中导入一个成员时(在本例中 FWCInput ),整个图书馆都被拉了进来,一切正常(包括 FWCDatepicker 该变量未在新变量中引用)。

    为什么会这样,作为库设计者,我们将如何允许用户只“使用”我们的组件,而不实例化一次性变量?

    编辑 :已删除 fwc.module.ts 文件,因为它不需要(来自之前的测试…)。

    1 回复  |  直到 8 月前
        1
  •  1
  •   Naren Murali    8 月前

    我认为你只需要将源代码添加到应用程序的根目录中,然后组件就会开始渲染。

    我们不能将组件添加到提供者中,因为它们只是类,提供者数组只接受具有装饰器的类 @Injectable() .

    我的理解是,只有导入源代码,你才能使用该组件。

    import '@foo/foo-web-components'; // <- changed here
    import { FWCInput, FWCDatepicker } from '@foo/foo-web-components';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      templateUrl: './app.component.html',
      styleUrl: './app.component.css',
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
    export class AppComponent {
      public today: Date = new Date();
      //@ts-ignore
      @ViewChild("datepicker") datepicker: ElementRef<FWCDatepicker>;
      //@ts-ignore
      @ViewChild("input") input: ElementRef<FWCInput>;
    
      constructor() { }
    
      ngAfterViewInit(): void {
        console.log(this.datepicker);
        console.log(this.input);
      }
    }