【问题标题】:Angular 2Injecting Components at run time using InterfacesAngular 2在运行时使用接口注入组件
【发布时间】:2020-09-01 02:28:59
【问题描述】:

一直在 angular 2 中搞乱,我正在尝试创建一个可以显示多种类型列表项的列表组件。

我的方法是分别创建各种类型的 ListItemComponents 并让它们实现 IListItemComponent 接口。然后我将通过我的父组件(主页)指定我的 listComponent 将使用哪种类型的 listItemComponent。

home.component.html(父)

<h2>Home</h2>
 <infinite-scroll>Loading</infinite-scroll>

home.component.ts(父)

import { Component, OnInit, provide, ViewChild } from '@angular/core';
import {InfiniteScrollComponent} from '../../core/components/infinite_scroll/infinite_scroll.component';
import { ImageBoardService } from '../../core/services/test.image_board.service';
import { DataProviderToken } from '../../core/injection/data_provider.token';
import {ImageBoardItemComponent} from '../../core/components/image_board_item/image_board_item.component';

@Component({
    moduleId: module.id,
    selector: '<home><home>',
    templateUrl: './home.component.html',
    directives: [InfiniteScrollComponent],
    providers: [provide(DataProviderToken, {useClass: ImageBoardService})]
})
export class HomeComponent implements OnInit {

    @ViewChild(InfiniteScrollComponent) private component: InfiniteScrollComponent;

    constructor() {
    }
    ngOnInit() {
        this.component.setItemComponent(ImageBoardItemComponent);
    }
}

infinite_scroll_component.html(列表)

<div class="infinate_scroll">
    <div #container> 
            
    </div>
</div>

infinite_scroll_component.ts(列表)

import { Component, Compiler, OnInit, Inject, ViewChild, ViewContainerRef,
        ComponentRef, ComponentFactory, ComponentFactoryResolver} from '@angular/core';
import {IDataProvider} from '../../interfaces/data_provider.interface';
import { DataProviderToken } from '../../injection/data_provider.token';
import { IListItemComponent } from '../../interfaces/list_item_component.interface';

@Component({
    moduleId: module.id,
    selector: 'infinite-scroll',
    templateUrl: 'infinite_scroll.component.html'
})
export class InfiniteScrollComponent implements OnInit {

    @ViewChild('placeholder', {read: ViewContainerRef}) viewContainerRef;
    private componentFactory: ComponentFactory<any>;

    private _dataProvider: IDataProvider;
    private _component: IListItemComponent;
    items: Array<any>;

    setItemComponent= function setItemComponent(component: IListItemComponent){
        this._component = component;
          this.viewContainerRef.createComponent(this.componentFactory, 0);
    };

    constructor(@Inject(DataProviderToken) private dataProvider: IDataProvider,
                componentFactoryResolver: ComponentFactoryResolver, compiler: Compiler) {
        this.componentFactory = componentFactoryResolver.resolveComponentFactory(this._component);
        this._dataProvider = dataProvider;
    }
    ngOnInit() {
       this.items = this._dataProvider.get();
    }
}

list_item_component.interface.ts(列表项接口)

export  interface IListItemComponent {

}

image_board_item.html(列表项)

<div>
    <div>{{test}}</div>
</div>

image_board_item.component.ts(列表项)

import { Component } from '@angular/core';
import { IListItemComponent} from '../../interfaces/list_item_component.interface';

@Component({
    moduleId: module.id,
    selector: 'image-board-item',
    templateUrl: 'image_board_item.html'
})
export class ImageBoardItemComponent implements IListItemComponent {
    test = 'test';
}

我在以下行中遇到问题 infinite_scroll_component.html

仍然不确定我想要做的事情是否可行。我可以将一个组件从我的主页传递给我的列表组件,它接受一个接口而不是一个组件。然后在运行时注入它?

【问题讨论】:

    标签: angular


    【解决方案1】:

    你可以试试下面,而不是接口创建一个具体的类,

    ListItemComponent

    @Component({})
    export  interface ListItemComponent {
    
    }
    

    然后像下面这样扩展ImageBoardItemComponent 类,

    ImageBoardItemComponent

    @Component({
      moduleId: module.id,
      selector: 'image-board-item',
      templateUrl: 'image_board_item.html'
    })
    export class ImageBoardItemComponent extends ListItemComponent {
       test = 'test';
    
       constructor(){
          super();
       }
    }
    

    当你有实际的组件类时创建组件工厂可能在setItemComponent函数中。

    接口不工作,因为resolveComponentFactory 需要一个具体的类,你可以阅读它here

    【讨论】:

      猜你喜欢
      • 2017-07-14
      • 2017-12-20
      • 1970-01-01
      • 2016-03-25
      • 2019-02-23
      • 2020-11-10
      • 2016-11-14
      • 1970-01-01
      • 2016-06-10
      相关资源
      最近更新 更多