2017-06-01 66 views
1

我有一個從它的調用者(App)接收數據的基本組件(MyBaseComponent)。如何將組件類型傳遞給Angular中的另一個組件?

我想知道是否有可能爲我的基本組件由它的調用什麼「顯示」部分應使用被告知 - MyDisplayComponentMyOtherDisplayComponent

也就是說,我想做的事的東西線:

<my-base [data]="names"> 
    <my-other-display></my-other-display> 
</my-base> 

,並在不同的位置,喜歡的東西:

<my-base [data]="names"> 
    <my-display></my-display> 
</my-base> 

但我無法弄清楚如何做這個。我嘗試了不同的使用<ng-content>,但我不認爲它提供了這種靈活性水平。另外ComponentFactoryResolver聽起來像它可以工作,但我不知道它如何以迭代的方式工作,以及將數據傳遞給子控件。

Here's a working Plunker,下面列出的代碼,希望傳達我試圖。

app.ts

import {Component, NgModule, VERSION} from '@angular/core' 
import {BrowserModule} from '@angular/platform-browser' 
import {MyBaseComponent} from './my-base.component' 
import {MyDisplayComponent} from './my-display.component' 
import {MyOtherDisplayComponent} from './my-other-display.component' 


@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <my-base [data]="names"> 

     <!-- Is it possible to specify the 'display component' type to use here? --> 

     </my-base> 
    </div> 
    `, 
}) 
export class App { 

    names: string[] = ["bill", "bob", "ben"]; 

    constructor() { 
    } 
} 

@NgModule({ 
    imports: [ BrowserModule ], 
    declarations: [ App, MyBaseComponent, MyDisplayComponent, MyOtherDisplayComponent ], 
    bootstrap: [ App ] 
}) 
export class AppModule {} 

我-base.component.ts

import {Component, Input} from '@angular/core' 

@Component({ 
    selector: 'my-base', 
    template: ` 
    <div *ngFor="let datum of data"> 

    <!-- Instead of specifying the display components here, 
    how can I specify the components type to use for display 
    at the 'app.ts' level? --> 

    <!--<my-display [value]="datum"></my-display>--> 
    <my-other-display [value]="datum"></my-other-display> 
    </div> 
    `, 
}) 
export class MyBaseComponent { 

    @Input() 
    data: string[]; 

    constructor() { 
    } 
} 

我-display.component.ts

import {Component, Input} from '@angular/core' 

@Component({ 
    selector: 'my-display', 
    template: ` 
    <div>{{value}}</div> 
    `, 
}) 
export class MyDisplayComponent { 
    @Input() 
    value:string; 

    constructor() { 
    } 
} 

我-其他-display.component.ts

//our root app component 
import {Component, Input} from '@angular/core' 

@Component({ 
    selector: 'my-other-display', 
    template: ` 
    <div>{{value}}! {{value}}! {{value}}!</div> 
    `, 
}) 
export class MyOtherDisplayComponent { 

    @Input() 
    value:string; 

    constructor() { 
    } 
} 

再次,大「問」這裏是它是否有可能在app.ts(調用)水平,使指定使用display組件my-base.component.ts文件可能無法瞭解特定情況下使用的特定實現。

這可能是my-base.component.ts文件需要傳遞一個類名或一個類型來使用它,以符合某種接口...?

在此先感謝您的幫助。

回答

1

1)您可以嘗試使用ngTemplateOutlet指令像

我-base.component.ts

@Component({ 
    selector: 'my-base', 
    template: ` 
    <div *ngFor="let datum of data"> 
     <ng-container *ngTemplateOutlet="tmpl; context: { $implicit: datum }"></ng-container> 
    </div> 
    `, 
}) 
export class MyBaseComponent { 
    @ContentChild(TemplateRef) tmpl: TemplateRef<any>; 

    @Input() data: string[]; 
} 

app.component.ts

@Component({ 
    selector: 'my-app', 
    template: ` 
    <my-base [data]="names"> 
     <ng-template let-item> 
     <my-other-display [value]="item"></my-other-display> 
     </ng-template> 
    </my-base> 

    <my-base [data]="names"> 
     <ng-template let-item> 
     <my-display [value]="item"></my-display> 
     </ng-template> 
    </my-base> 
    `, 
}) 
export class App { 
    names: string[] = ["bill", "bob", "ben"]; 
} 

Forked Plunker

2)使用ngForTemplate。幾乎只有一個區別同樣的方法在

我-base.component.ts

@Component({ 
    selector: 'my-base', 
    template: `<div *ngFor="let datum of data; template: tmpl"></div>` 
}) 
export class MyBaseComponent { 
    @ContentChild(TemplateRef) tmpl: TemplateRef<any>; 

    @Input() data: string[]; 
} 

Forked Plunker ngForTemplate

+0

這是非常好的 - 正是我所期待的。非常感謝! – Cuga

-1

如果我理解正確的,你可以使用NgSwitch

<div [ngSwitch]="typeOfComponent"> 
    <my-display [value]="datum" *ngSwitchCase="type1"></my-other-display> 
    <my-other-display [value]="datum" *ngSwitchCase="type2"></my-other-display> 
    <my-other-display [value]="datum" *ngSwitchCase="type3"></my-other-display>  
</div> 
+0

的問題是,是否有可能有** app.ts * *「調用者」代碼指定將哪些組件用作顯示爲某種變量。這對此沒有任何幫助。 – Cuga

+0

您可以使用app.ts中的某些屬性啓動服務,並在基本組件中注入該服務,並根據這些屬性顯示您想要的內容。 –

0

代替NG-內容,你可以簡單地解決使用if和else。

基部部件將通過真或假的值處呈現

應用程序。TS

<my-base [data]="names" [isValid]=false> 

MyBaseComponent.ts

<div *ngIf="isValid;then content else other_content"></div> 

<ng-template #content> <div *ngFor="let datum of data"> 
    <my-display [value]="datum"></my-display> 
    </div></ng-template> 
<ng-template #other_content> <div *ngFor="let datum of data"> 

    <my-other-display [value]="datum"></my-other-display> 
    </div></ng-template> 
+0

問題是我不想將任何組件硬編碼到MyBaseComponent中。我想要在** app.ts **級別指定它們。 – Cuga

0

您可以使用ngComponentOutlet選擇組件,可能ngIf或交換機,以展示,我不知道你的打算是什麼對於。

Plunker

<ng-container *ngComponentOutlet="MyDisplayComponent"></ng-container> 

// in module 
entryComponents : [ MyDisplayComponent, MyOtherDisplayComponent], 
+0

我看到您的更新。因此,在這種情況下,'顯示'組件如何將「名稱」作爲輸入傳遞給它們?在給定的運動員,沒有任何呈現 – Cuga

相關問題