2017-08-24 7 views
0

重複の可能性はありますが、私のシナリオは少し異なります。ダイナミックコンポーネントクリックイベントバインディング - 角度2

動的コンポーネントのクリックイベントを実行したいとします。ここ

は私の構造体である:

 <razor> 
      <mvc-partial> 
      <dynamic-html> // buttonPress(){console.log("Function called in dynamicHtml) 
          // Output() to call function in razor.ts 
      </dynamic-html> 
      </mvc-partial> 
     <razor> 

RenderingViewDynamic.tsは

import { 
    Component, 
    Directive, 
    NgModule, 
    Input, 
    Output, 
    EventEmitter, 
    ViewContainerRef, 
    Compiler, 
    ComponentFactory, 
    ModuleWithComponentFactories, 
    ComponentRef, 
    ReflectiveInjector, OnInit, OnDestroy, ViewChild 
} from '@angular/core'; 

import { RouterModule } from '@angular/router'; 
import { CommonModule } from '@angular/common'; 
import { Http } from "@angular/http"; 
import 'rxjs/add/operator/map'; 

export function createComponentFactory(compiler: Compiler, metadata: Component): Promise<ComponentFactory<any> | undefined>{ 
    console.log(compiler) 
    console.log(metadata) 
    class DynamicComponent { 
     @Output() buttonType: EventEmitter<string> = new EventEmitter<string>() 

     // button click operation 
     buttonPress() { 
      this.buttonType.emit(); 
     } 
    }; 
    const decoratedCmp = Component(metadata)(DynamicComponent); 

    @NgModule({ imports: [CommonModule, RouterModule], declarations: [decoratedCmp] }) 
    class DynamicHtmlModule { } 

    return compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule) 
     .then((moduleWithComponentFactory: ModuleWithComponentFactories<any>) => { 
      console.log(decoratedCmp) 
      console.log(moduleWithComponentFactory.componentFactories.find(x => x.componentType === decoratedCmp)) 
      return moduleWithComponentFactory.componentFactories.find(x => x.componentType === decoratedCmp); 
     }); 
} 

@Component({ 
    selector: 'mvc-partial', 
    template: `<div #dynamicHtml></div>` 
}) 
//@Directive({ selector: 'mvc-partial' }) 
export class RenderingViewDynamic implements OnInit { 
    @ViewChild('dynamicHtml', { read: ViewContainerRef }) target: ViewContainerRef; 
    html: string = '<p></p>'; 
    @Input() url: string; 
    cmpRef: ComponentRef<any>; 

    constructor(private vcRef: ViewContainerRef, private compiler: Compiler, private http: Http) { } 

    ngOnInit() { 
     this.http.get(this.url) 
      .map(res => res.text()) 
      .subscribe(
      (html) => { 
       this.html = html; 
       if (!html) return; 

       if (this.cmpRef) { 
        this.cmpRef.destroy(); 
       } 

       const compMetadata = new Component({ 
        selector: 'dynamic-html', 
        template: this.html, 
       }); 

       createComponentFactory(this.compiler,compMetadata) 
        .then(factory => { 
         //const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector); 
         this.cmpRef = this.target.createComponent(factory!); 
        }); 
      }, 
      err => console.log(err), 
      () => console.log('MvcPartial complete') 
      ); 

    } 

    ngOnDestroy() { 
     if (this.cmpRef) { 
      this.cmpRef.destroy(); 
     } 
    } 

} 

razor.component.html

<mvc-partial [url]="'/View/Index'" (buttonType)="click()"></mvc-partial>

razor.component.ts

を提出します

click(){ console.log("In razor") }

私の質問は、ボタンが私のdynamic-htmlにあり、イベントをrazor.tsの関数にバインドしたいと考えています。

<dynamic-html>-<mvc-partial>-<razor>どうすれば実現できますか?

更新:サービス

class DynamicComponent { 
     constructor(private appService: AppService) { } 

     buttonPress() { 
      this.appService.onButtonClickAction.emit() 
     } 
    }; 
    const decoratedCmp = Component(metadata)(DynamicComponent); 

    @NgModule({ imports: [CommonModule, RouterModule], declarations: [decoratedCmp], providers: [AppService] }) 

エラーと通信しようとすると、ポップ:はDynamicComponentのすべてのパラメータを解決できません:(?)。

clickEmitter = new EventEmitter(); 

clickEmitter.emit(); 

<your-child-component (clickEmitter)="functionInParent()"></your-child-component> 

編集:

enter image description here

上記のエラーは、あなたが持つEventEmitterを使用して、バブルアップあなたの親にあなたの子供からのクリックイベントをすることができます@Inject(forwardRef(() => AppService)

constructor(@Inject(forwardRef(() => AppService)) private appService: AppService) { } 
+0

() 'を動的に追加します。参照するには、https://stackoverflow.com/questions/36325212/angular-2-dynamic-tabs-with-user-click-chosen-components/36325468#36325468で私の答えの最初のコードブロックのコメントアウトされたコードを参照してください動的に追加されたコンポーネントとの通信方法共有サービスも同様に使用できます。 –

+0

@GünterZöchbauerhttps://stackoverflow.com/questions/40725620/angular-2-dynamic-component-click-eventどのように私を助けるつもりですか? – k11k2

+0

動的に追加されたHTML –

答えて

0

を追加することで解決しますあなたのコメントごとに子コンポーネントにアクセスしたい場合:<dynamic-html>-<mvc-partial>-<razor>あなたは、ハッシュタグのハッシュタグ(#)と名前を使用してコンポーネントを参照したりすることができ、コンポーネント名によって

@ViewChild(MvcPartialComponent) mvcPartialComponent: MvcPartialComponent; 

<mvc-partial #mvc-partial></mvc-partial> 
@ViewChild('mvc-partial') mvcPartialComponent: MvcPartialComponent; 

などなどあなたが `@output()`や `@Inputを使用することはできません

+0

上記のシナリオでは実行できません。原因の流れがある '<ダイナミックHTML> - - 'ボタンを動的html'と機能を次に、あなただけのコンポーネントの参照を設定することができますし、直接関数を呼び出すrazor' – k11k2

+0

'で呼ばれるべき'です。私の更新された答え – Carsten

+0

よろしくお願いします。しかし、私のボタンは 'dynamic-html'にあります。' DynamicComponent'でそれを扱っていますので、 'MvcPartialComponent'の参照はうまくいかないでしょう。 (DynamicComponent) 'dynamic-html' – k11k2