在子事件点击时在父母中执行操作

时间:2018-02-11 04:04:15

标签: node.js angular angularjs-directive electron angular5

因此,当在子组件中触发click事件时,我正在尝试对子组件的父组件执行某些操作。目前我有一个动态加载器,它能够加载不同的子组件。我遇到的问题是@Output()正在被发出,但是当触发此事件时,父组件似乎没有任何知识。有什么我想念的吗?

  

child2.component.ts

import {Component, Injector, Output, EventEmitter} from '@angular/core';

@Component({
  selector: 'hello-world',
  template: `
    <div>Hello World {{showNum}}</div>
    <li (click)="childButtonClicked(false)"> </li>
  `,
})
export class HelloWorldComponent {
  showNum = 0;
  @Output() childEvent = new EventEmitter<boolean>();

  constructor(private injector: Injector) {
    this.showNum = this.injector.get('showNum');
     console.log("HelloWorldComponent");
  }

  childButtonClicked(agreed: boolean) {
    this.childEvent.emit(agreed);
    console.log("clicked");
  }
}
  

child1.component.ts

import {Component, Injector, Output, EventEmitter} from '@angular/core';

@Component({
  selector: 'world-hello',
  template: `
    <div>World Hello {{showNum}}</div>
    <li (click)="childButtonClicked(false)"> </li>
  `,
})
export class WorldHelloComponent {
  showNum = 0;
  @Output() childEvent = new EventEmitter<boolean>();

  constructor(private injector: Injector) {
    this.showNum = this.injector.get('showNum');
     console.log("WorldHelloComponent");
  }

  childButtonClicked(agreed: boolean) {
    this.childEvent.emit(agreed);
    console.log("clicked");
  }
}
  

dynamic.componentloader.ts

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

@Component({
  selector: 'dynamic-component',// Reference to the components must be here in order to dynamically create them
  template: `
    <div #dynamicComponentContainer></div>
  `,
})
export class DynamicComponent {
  currentComponent:any = null;

  @ViewChild('dynamicComponentContainer', { read: ViewContainerRef }) dynamicComponentContainer: ViewContainerRef;

  // 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 }) {
    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) {
      this.currentComponent.destroy();
    }

    this.currentComponent = component;
  }

  constructor(private resolver: ComponentFactoryResolver) {

  }
}
  

main.component.ts

import { Component, OnInit } from '@angular/core';
import { HelloWorldComponent } from '../../views/main/sidebar-views/comps/hello-world.component';
import { WorldHelloComponent } from '../../views/main/sidebar-views/comps/world-hello.component';

@Component({
    selector: 'main-component',
    template:  require('./main.component.html')
})
export class MainComponent {
    private pressed: boolean = false;
    componentData:any = null;

    constructor() { }

    createHelloWorldComponent(){
        this.componentData = {
        component: HelloWorldComponent,
        inputs: {
            showNum: 9
        }
        };
    }

    createWorldHelloComponent(){
        this.componentData = {
        component: WorldHelloComponent,
        inputs: {
            showNum: 2
        }
        };
    }

    test(){
        console.log("some click event");
    }

};
  

main.component.html

<div>
  <h2>Lets dynamically create some components!</h2>
  <button (click)="createHelloWorldComponent()">Create Hello World</button>
  <button (click)="createWorldHelloComponent()">Create World Hello</button>
  <dynamic-component [componentData]="componentData" (childEvent)="test()"></dynamic-component>
</div>

1 个答案:

答案 0 :(得分:0)

由于您要将参数传递给EventEmitter,因此您需要将模板中组件选择器的事件绑定更改为:

<dynamic-component [componentData]="componentData" (childEvent)="test($event)"></dynamic-component>

另外,不要忘记更改组件中的功能签名以接受参数:

test(agreed: boolean){
    console.log("some click event");
}

有关official docs的更多信息。