2017-02-03 30 views
9

に出力を使用しますどのように私は動的にコンポーネントを作成するためにこの技術を使用しています動的に作成したコンポーネント

import { 
Component, Input, ViewContainerRef, ViewChild, ReflectiveInjector, ComponentFactoryResolver, 
Output, EventEmitter 
} from '@angular/core'; 

@Component({ 
selector: 'dynamic-component', 
template: ` 
<div #dynamicComponentContainer></div> 
`, 
}) 
export default class DynamicLayerComponent { 
currentComponent = null; 

@ViewChild('dynamicComponentContainer', { read: ViewContainerRef })  dynamicComponentContainer: ViewContainerRef; 
@Output() visibility = new EventEmitter<boolean>(); 

// component: Class for the component you want to create 
// inputs: An object with key/value pairs mapped to input name/input value 
@Input() set componentData(data: {component: any, inputs: any }) { 
console.log('setting'); 
if (!data) { 
    return; 
} 

// Inputs need to be in the following format to be resolved properly 
let inputProviders = Object.keys(data.inputs).map((inputName) => {return {provide: inputName, useValue: data.inputs[inputName]};}); 
let resolvedInputs = ReflectiveInjector.resolve(inputProviders); 

// We create an injector out of the data we want to pass down and this components injector 
let injector = ReflectiveInjector.fromResolvedProviders(resolvedInputs, this.dynamicComponentContainer.parentInjector); 

// We create a factory out of the component we want to create 
let factory = this.resolver.resolveComponentFactory(data.component); 

// We create the component using the factory and the injector 
let component = factory.create(injector); 

// We insert the component into the dom container 
this.dynamicComponentContainer.insert(component.hostView); 

// We can destroy the old component is we like by calling destroy 
if (this.currentComponent) { 
    console.log('fdsafa'); 
    this.currentComponent.destroy(); 
} 

this.currentComponent = component; 
} 

constructor(private resolver: ComponentFactoryResolver) { 
    console.log('dfsd'); 
} 
} 

をそして私はそのようにそれを使用する:

<div *ngFor="let layer of sortedItems" class="single-layer"> 
    <div> 
    <dynamic-component #DynamicLayer 
         [componentData]="{ 
    component: layer.componentClass, 
    inputs: { 
    layerItem: layer, 
    sortFilter: sortFilter 
    } 
}" 
         (visibility)="setLayerVisibility(layer, $event)"> 
    </dynamic-component> 
    </div> 

問題は、私はないですということですイベントにバインドすることができますが、バインディング時(可視性)には機能しません。 setLayerVisibilityは、イベントが発生したときに呼び出されません。その問題を解決するには?

@Output() visibility = new EventEmitter<boolean>(); 

private visibilityChanged() { 
    this.visibility.emit(this.layerItem.visible); 
    } 
+0

まだ問題がある場合:

あなたは経由してそのイベントをサブスクライブするだろうか? – mxii

答えて

12

あなたの工場:

はもちろんcomponentClassに基づいて私の試料成分は@outputは次のように設定している

factory.create(injector); 

はComponentRefオブジェクトを返します、そしてこのオブジェクトにあなたはそれにアクセスすることができますコンポーネント自体。

component.instance.visibility.subscribe(v => ...); 
関連する問題