首页 > 解决方案 > 将组件用作自定义元素和角度组件

问题描述

我正在尝试使用 Angular 组件作为自定义元素,这样我就可以动态地将它添加到 DOM 中,并且它会自动引导,但我还需要这个组件作为另一个组件模板的一部分。

我已将Description组件注册为自定义元素,并且只要我将以下内容添加到 dom,它就会正确引导:

<app-description text="Some description text..."></app-description>

但是,如果我想将该组件用作Header组件模板(正确设置了属性 descriptionText)的一部分,则不会显示任何描述。我这样使用它:

<app-description text="{{descriptionText}}"></app-description>

我也试过:

<app-description [text]="descriptionText"></app-description>

<app-description text="descriptionText"></app-description>

但无论如何我都没有得到预期的结果。

所以,我的问题是: 有没有办法将 Angular 组件定义为自定义元素,并且还能够将其包含在任何 Angular 组件的模板中?

编辑: 我在 Header 和 Description 组件的 ngOnInit 方法中放置了一个 console.log() ,我在控制台中打印了这个:

在此处输入图像描述

似乎组件被初始化了两次,第二次“文本”设置为未定义?

描述组件:

@Component({
  selector: 'app-description',
  templateUrl: './description.component.html',
  styleUrls: ['./description.component.css']
})
export class DescriptionComponent implements OnInit {
  @Input() text: String;

  constructor() {}

  ngOnInit() {
    console.log('text:', this.text)
  }
}

说明模板:

<div class="description">
    <h3>{{ text }}</h3>
</div>

标题组件:

  @Component({
    selector: 'app-header',
    templateUrl: './header.component.html',
    styleUrls: ['./header.component.less']
  })
  export class HeaderComponent implements OnInit {
    @Input() title: String;
    @Input() subtitle: String;
    @Input() descriptionText: String;

    constructor() {}

    ngOnInit() {
      console.log('descriptionText:', this.descriptionText)
    }
  }

标题模板:

<div class="header flex-container">
    <h1>{{ title }}</h1>
    <h2>{{ subtitle }}</h2>
    {{descriptionText}} <!-- shown correctly! -->
    <app-description text="{{descriptionText}}"></app-description>
</div>

模块:

@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    DescriptionComponent
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [],
  entryComponents: [
    AppComponent,
    HeaderComponent,
    DescriptionComponent
  ],
  schemas : [
    CUSTOM_ELEMENTS_SCHEMA
  ]
}) 

export class AppModule {
  constructor(private injector: Injector) {
    this.registerCustomElements();
  }

  ngDoBootstrap() {}

  registerCustomElements() {
    const HeaderElement = createCustomElement(HeaderComponent, {injector: this.injector});
    customElements.define('app-header', HeaderElement);

    const DescriptionElement = createCustomElement(DescriptionComponent, {injector: this.injector});
    customElements.define('app-description', DescriptionElement);
  }
}

我正在使用 Angular 6 中提供的 Angular 自定义元素

谢谢!

标签: angularweb-componentangular6custom-element

解决方案


好的,我使用以下代码解决了问题,问题与嵌套 css 代码相关,然后您需要在<app-description>下面的行中放入您的子自定义元素(在这种情况下)encapsulation: ViewEncapsulation.None,我将 var 更改descriptionTestdescription

描述.component.ts

@Component({
  selector: 'app-description',
  templateUrl: './description.component.html',
  styleUrls: ['./description.component.css'],
  encapsulation: ViewEncapsulation.None
})

描述.component.html

<div>
    {{text}}
</div>

header.component.ts

  @Input() title: String;
  @Input() subtitle: String;
  @Input() description: String;

header.component.html

    <div class="header flex-container">
      <h1>{{ title }}</h1>
      <h2>{{ subtitle }}</h2>
      {{description}} <!-- shown correctly! -->
      <app-description text="{{description}}"></app-description>
    </div>

**App.module.ts**

@NgModule({
  declarations: [
    AppComponent,      
    HeaderComponent,
    DescriptionComponent  
  ],
  imports: [
    BrowserModule,    
  ],  
  providers: [],
  entryComponents:[
    HeaderComponent,
    DescriptionComponent
  ],
  bootstrap: []
})
export class AppModule {
  constructor(private injector: Injector) {

  }

  ngDoBootstrap() {
    this.registerCustomElements();
  }

  registerCustomElements() {
    const DescriptionElement = createCustomElement(DescriptionComponent, {injector: this.injector});
    customElements.define('app-description', DescriptionElement);

    const HeaderElement = createCustomElement(HeaderComponent, {injector: this.injector});
    customElements.define('app-header', HeaderElement);       
  }

索引.html

 <app-root>
  </app-root>
  <app-description text="'HOLA!'"></app-description>

  <app-header title="Title"
      subtitle="Subtitle"
      description="DESCRIPTION"
  ></app-header>

源代码

输出

带有此示例的github 存储库


推荐阅读