2017-03-01 12 views
12

動的にあなたがngComponentOutletディレクティブを使用することができますコンポーネントを作成する4角:このようなhttps://angular.io/docs/ts/latest/api/common/index/NgComponentOutlet-directive.html角度4+ ngComponentOutlet動的に作成コンポーネントの@Inputを割り当てるには

何か:

ダイナミックコンポーネントを

@Component({ 
    selector: 'dynamic-component', 
    template: ` 
    Dynamic component 
    ` 
}) 
export class DynamicComponent { 
    @Input() info: any; 
} 

アプリ

@Component({ 
    selector: 'my-app', 
    template: ` 
    App<br> 
    <ng-container *ngComponentOutlet="component"></ng-container> 
    ` 
}) 
export class AppComponent { 
    this.component=DynamicComponent; 
} 

@Input() info: any;このテンプレートの情報を<ng-container *ngComponentOutlet="component"></ng-container>に渡すにはどうすればよいですか?

+0

何 'Input' @のために特別に作られて使用することができるため、私はと思いますか? 。 –

+1

テンプレートから動的に作成されたコンポーネントに情報をどのように送信しますか? @Inputデコレータなどを使用していますか? –

+1

「テンプレートから」という意味で、どこから何の情報が得られるかによって異なります。サポートが必要な場合は、詳細を提供する必要があります。 –

答えて

6

このような機能は、ngComponentOutletのプルリクエストで説明されていましたが、今は削除されました。 はさえhttps://angular.io/docs/ts/latest/api/common/index/NgComponentOutlet-directive.htmlに現在表示されているcomponentRefは、パブリックではないため、使用できませんhttps://github.com/angular/angular/blob/3ef73c2b1945340ca6bd21f1790260c88698ae26/modules/%40angular/common/src/directives/ng_component_outlet.ts#L78

Angular 2 dynamic tabs with user-click chosen components

this.compRef.instance.someProperty = 'someValue'; 
に示したように、私はあなたが https://github.com/angular/angular/blob/3ef73c2b1945340ca6bd21f1790260c88698ae26/modules/%40angular/common/src/directives/ng_component_outlet.ts#L72

由来独自のディレクティブを作成し、入力する値を割り当てることをお勧めしたい

+0

ありがとうございます。 v4.0がリリースされるまでに異なるngComponentOutletを持つことは可能ですか?私はこの問題に対処するいくつかのオプションを意味しますか? –

+0

私は計画について知らない。結論は、入力をサポートすることは最初のバージョンでは複雑すぎるということであり、それをそのままリリースし、最終的にはその問題に再びアプローチしたいと考えていましたが、その後も関連する議論は見られませんでした。 –

+0

@GünterZöchbauerしたがって、 'ngComponentOutlet'でコンポーネントを動的に呼び出すと、現在のテンプレート/コンポーネントから' model'や 'data'を動的コンポーネントに送る唯一の方法は、カスタムディレクティブか、何らかのサービス権を使用していますか? 'ngComponentOutlet'は、呼び出し元と呼び出し先の両方のコンポーネントを通信するための組み込み機能を持っていませんか? 'ngComponentOutletInjector'さえありませんか? – SrAxi

6

@GünterZöchbauerの投稿の助けを借りて、私はこのようにして同様の問題を解決しました。あなたは何とかそれを適用できることを願っています。

まず私は、いくつかのインターフェースを定義:

// all dynamically loaded components should implement this guy 
export interface IDynamicComponent { Context: object; } 

// data from parent to dynLoadedComponent 
export interface IDynamicComponentData { 
    component: any; 
    context?: object; 
    caller?: any; 
} 

は、私は、動的にロードされたコンポーネントその後

dynamicLoadedComponentA.ts

// ... 
export class DynamicLoadedComponentA implements IDynamicComponent { 
// ... 

// data from parent 
public Context: object; 

// ... 

の内部にそれらを実装Iが構築魔法を担当する新しいコンポーネント。ここで重要なのは、すべてのdynを登録しなければならないということです。 entryComponentsとしてロードされたコンポーネント

ここdynamic.component.ts

@Component({ 
    selector: 'ngc-dynamic-component', 
    template: ´<ng-template #dynamicContainer></ng-template>´, 
    entryComponents: [ DynamicLoadedComponentA ] 
}) 
export class DynamicComponent implements OnInit, OnDestroy, OnChanges { 
    @ViewChild('dynamicContainer', { read: ViewContainerRef }) public dynamicContainer: ViewContainerRef; 

    @Input() public componentData: IDynamicComponentData; 

    private componentRef: ComponentRef<any>; 
    private componentInstance: IDynamicComponent; 

    constructor(private resolver: ComponentFactoryResolver) { } 

    public ngOnInit() { 
    this.createComponent(); 
    } 

    public ngOnChanges(changes: SimpleChanges) { 
    if (changes['componentData']) { 
     this.createComponent(); 
    } 
    } 

    public ngOnDestroy() { 
    if (this.componentInstance) { 
     this.componentInstance = null; 
    } 
    if (this.componentRef) { 
     this.componentRef.destroy(); 
    } 
    } 

    private createComponent() { 
    this.dynamicContainer.clear(); 
    if (this.componentData && this.componentData.component) { 
     const factory: ComponentFactory<any> = this.resolver.resolveComponentFactory(this.componentData.component); 
     this.componentRef = this.dynamicContainer.createComponent(factory); 
     this.componentInstance = this.componentRef.instance as IDynamicComponent; 

     // fill context data 
     Object.assign(this.componentInstance.Context, this.componentData.context || {}); 

     // register output events 
     // this.componentRef.instance.outputTrigger.subscribe(event => console.log(event)); 
    } 
    } 
} 

このピカピカの新しいものの使用:

app.html

<!-- [...] --> 
<div> 
    <ngc-dynamic-component [componentData]="_settingsData"></ngc-dynamic-component> 
</div> 
<!-- [...] --> 

アプリTS

// ... 
    private _settingsData: IDynamicComponent = { 
    component: DynamicLoadedComponentA, 
    context: { SomeValue: 42 }, 
    caller: this 
    }; 
// ... 
+0

このソリューションは、事前にコンパイルしても動作しますか? –

+1

現在、AOTでテストされていませんが、近い将来にこれをテストし、私の投稿を補完します。 –

関連する問題