2016-08-20 51 views
0

在角2中乱搞,我尝试创建一个可以显示多种类型的列表项的列表组件。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_com ponent.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

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

回答

0

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

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

希望这有助于!