如何通过点击事件传达父子组件

时间:2019-09-26 08:35:38

标签: angular typescript function dom-events

我有一个Angular 8应用程序。而且我有亲子关系。

所以我在父DossierCorrespondenceComponent中有一个函数,但是必须在子组件中触发该函数。

所以我在父级中具有此功能:

@Input()  myGotoItem: Function;


gotoItem(index, type: string) {
    this.showingSingle = true;

    switch (type) {
      case 'correspondence': {
        this.single = this.correspondenceEntries[index];
        break;
      }
      case 'attachments': {
        this.single = this.attachmentEntries[index];
        break;
      }
      default: {
        break;
      }
    }
    this.showingSingle = true;
  }

我尝试像这样在子组件DossierCorrespondenceListComponent中调用它:

 <tr class="dossier-correspondencerow" *ngFor="let entry of correspondenceEntries; let i = index" (myGotoItem)="gotoItem(i, entry.type)">

但是什么也没发生

那我要改变什么?

但是我还有另一个组件DossierCorrespondenceAttachmentsComponent,它也使用了该功能:

 <tr class="dossier-correspondencerow" *ngFor="let entry of attachmentEntries; let i = index" (click)="gotoItem(i, entry.type)">

因此,如果我不得不将功能gotoItem(index, type: string)移到两个子组件上,而我却没有重复的代码。

我现在在父组件中有这样的内容:

<ng-container *ngIf="correspondenceEntries">
    <app-dossier-correspondence-list [correspondenceEntries]="correspondenceEntries" (onClick)="gotoItem(i, entry.type)"> </app-dossier-correspondence-list>
  </ng-container>

和ts父组件:

gotoItem(index, type: string) {
    this.showingSingle = true;

    switch (type) {
      case 'correspondence': {
        this.single = this.correspondenceEntries[index];
        break;
      }
      case 'attachments': {
        this.single = this.attachmentEntries[index];
        break;
      }
      default: {
        break;
      }
    }
    this.showingSingle = true;
  }

和子组件:

  <tbody class="dossier-tablebody">
          <tr class="dossier-correspondencerow" *ngFor="let entry of correspondenceEntries; let i = index" (click)="gotoItem(i, entry.type)">
            <td>{{ entry.date | date:"dd-MM-y" }}</td>
            <td>{{ entry.name }}</td>
          </tr>
        </tbody>



和ts子组件:


export class DossierCorrespondenceListComponent implements OnInit {

  @Input()
  correspondenceEntries: DossierEntry[];

  @Output()
  onClick = new EventEmitter();

  @Input() showingSingle;

  constructor() { }

  ngOnInit() {
  }

  ngOnChanges(changes) { console.log(changes)}

  click() {
    this.onClick.emit();
  }


}

但随后出现此错误:

dossier-correspondence-list.component.html:13 ERROR TypeError: _co.gotoItem is not a function
    at Object.handleEvent (dossier-correspondence-list.component.html:13)
    at handleEvent (core.js:29733)
    at callWithDebugContext (core.js:30803)
    at Object.debugHandleEvent [as handleEvent] (core.js:30530)
    at dispatchEvent (core.js:20520)
    at core.js:28942
    at HTMLTableRowElement.<anonymous> (platform-browser.js:1009)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Object.onInvokeTask (core.js:26760)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)

我改变了这个:

 click() {
    this.onClick.emit(true);
  }

dossier-correspondence-item.component.ts:51 ERROR TypeError: _co.gotoItem is not a function
    at Object.handleEvent (dossier-correspondence-item.component.ts:51)
    at handleEvent (core.js:29733)
    at callWithDebugContext (core.js:30803)
    at Object.debugHandleEvent [as handleEvent] (core.js:30530)
    at dispatchEvent (core.js:20520)
    at core.js:28942
    at HTMLTableRowElement.<anonymous> (platform-browser.js:1009)
    at 

3 个答案:

答案 0 :(得分:1)

DossierCorrespondenceComponent.html

<app-child (callYourFunction)="yourFunction()"</app-child>

DossierCorrespondenceComponent.ts

yourFunction() {
}

child.component.ts

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

@Output() callYourFunction = new EventEmitter();

在您要调用父组件的情况下:

this.callYourFunction.emit(true)

答案 1 :(得分:1)

父组件

<child (onClick)="gotoItem()"></child>

gotoItem() {
    //do something
}

子组件

<tr class="dossier-correspondencerow" *ngFor="let entry of attachmentEntries; let i = index" (click)="click()">

@Output() onClick = new EventEmitter();

click() {
    // do something
    this.onClick.emit()
}

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

父组件(html)

<app-dossier-correspondence-list [correspondenceEntries]="correspondenceEntries" (onClick)="gotoItem($event)"> </app-dossier-correspondence-list>

父项(ts)

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

  gotoItem(e) {
    console.log(e)
  }

}

子组件

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

@Component({
  selector: 'app-dossier-correspondence-list',
  template: `
    <table>
      <tr *ngFor="let entry of attachmentEntries; let i = index" (click)="click(i, entry.type)">
        {{entry.type}}
      </tr>
    </table>
  `
})
export class AppDossierCorrespondenceComponent  {

  @Input() correspondenceEntries: any;
  @Output() onClick = new EventEmitter();

  attachmentEntries = [
    { type: 'type1' },
    { type: 'type2' },
    { type: 'type3' },
  ]

  click(i, type) {
    this.onClick.emit({
      i: i,
      type: type
    })
  }

}

链接:https://stackblitz.com/edit/angular-ev6e5n

答案 2 :(得分:1)

父组件:

import { Component } from '@angular/core';

@Component({
 selector: 'my-app',
 template: `
  <hello [name]="name" (callParentFunc)="parentFunc()"></hello>
  <p [class.red]="clicked">
   This is text from parent component
  </p>
 `,
 styles: [`
  p {
   font-family: Lato;
  }

  p.red {
   color: red;
  }
`]
})
export class AppComponent  {
 name = 'Click me';
 clicked: boolean;

 parentFunc() {
  this.clicked = !this.clicked;
 }
}

子组件:

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

@Component({
 selector: 'hello',
 template: `<h1>
 Child component <a (click)="childClick()">{{name}}</a>
  </h1>`,
 styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent  {
 @Input() name: string;
 @Output() callParentFunc: EventEmitter<any> = new EventEmitter<any>();

 childClick() {
  this.callParentFunc.emit();
 }
}

我为您创建了stackblitz,这可能会有所帮助:

https://stackblitz.com/edit/angular-c9egd6