在我的简化场景中,有一个parent组件,其中包含所有业务逻辑.

parent创建child组件,该组件仅负责显示按钮列表.

我想处理parent中此类按钮的点击事件,但是,使用建议的EventEmitter模式,我不得不在parent中使用无用的switch case,以检测按下了哪个按钮.

直接将回调作为child的输入传递要容易得多,但我认为这不是一个好做法.而且,据我所知,这些回调是在子对象的上下文中执行的,这不是期望的结果.

我错过什么了吗?有没有更好的方法来满足我的需求?或者我完全以错误的方式处理这个问题?

The parent:

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

@Component({
  selector: "parent",
  template: ` <child
      [buttons]="buttons"
      (click)="onButtonClick($event)"
    ></child>
    <span>{{ description }}</span>`
})
export class ParentComponent {
  description = "";
  buttons = ["foo", "bar", "baz"];

  onButtonClick(button: string) {
    switch (button) {
      case "foo":
        this.description = "Calling foo()";
        this.foo();
        break;
      case "bar":
        this.description = "Calling bar()";
        this.bar();
        break;
      case "baz":
        this.description = "Calling baz()";
        this.baz();
        break;
    }
  }

  foo() {}
  bar() {}
  baz() {}
}

The child:

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

@Component({
  selector: "child",
  template: ` <span *ngFor="let button of buttons">
    <button (click)="onClick(button)">{{ button }}</button>
  </span>`
})
export class ChildComponent {
  @Input() buttons: string[];

  @Output() click = new EventEmitter<string>();

  onClick(button: string) {
    this.click.emit(button);
  }
}

And a working 100.

推荐答案

你可以emits 任何东西

//家长

@Component({
  selector: "parent",
  template: ` <child
      [buttons]="buttons" (click)="$event()"
    ></child>
    <span>{{ description }}</span>`
})
export class ParentComponent {
  description = "";
  buttons = [
    { name: "foo", callback: this.foo},
    { name: "bar", callback: this.bar},
    { name: "baz", callback: this.baz},
  ];
  foo(){}
  bar(){}
  baz(){}
}

// children

@Component({
  selector: "child",
  template: ` <span *ngFor="let button of buttons">
    <button (click)="onClick(button)">{{ button.name }}</button>
  </span>`
})
export class ChildComponent {
  @Input() buttons: any[];

  @Output() click = new EventEmitter<any>();

  onClick(button: any) {
    this.click.emit(button.callback);
  }
}

Update声音"bizarro"传递函数并使用function()执行,但我们需要认为函数只是一个对象.

假设您定义了两个函数

function1(){console.log("I'm function 1")}
function2(){console.log("I'm function 1")}

在事件单击中,我们调用函数

click()
{
   const mainFunction=this.function1
   mainFunction() //execute the function1
}

或者根据变量

click()
{
   const mainFunction=this.condicion?this.function1:this.function2
   mainFunction() //execute the function1 or the function2 
                  //if condition is true or false
}

变量、对象、数组、函数...物理存储在内存位置.变量、对象、函数的"名称"...只是指向此内存的"指针".

如果我们愿意,我们可以在答案中写下

    <child [buttons]="buttons" (click)="executeFunction($event)"></child>

   executeFunction(mainFunction:any)
   {
         mainFunction()
   }

如果我们想要,我们可以键入函数,使其更加清晰,如果我们所有的函数都没有参数,也没有返回任何内容,那么可以使用这个丑陋的"any"用法

   executeFunction(mainFunction:()=>void)
   {
         mainFunction()
   }

@Output() click = new EventEmitter<()=>void>();

Javascript相关问答推荐

如何在JavaScript中通过一次单击即可举办多个活动

有什么(最佳)方法可以从模块中获取脚本模块的多姆元素吗?

Angular 17—每当一个布尔变量变为真时触发循环轮询,只要它保持为真

给定一个凸多边形作为一组边,如何根据到最近边的距离填充里面的区域

cypress中e2e测试上的Click()事件在Switch Element Plus组件上使用时不起作用

在Three JS中看不到补间不透明度更改效果

在JS中拖放:检测文件

WhatsApp Cloud API上载问题:由于MIME类型不正确而导致接收&Quot;INVALID_REQUEST";错误

在forEach循环中获取目标而不是父对象的属性

获取';无法解决导入和导入";slick-carousel/slick/slick-theme.css";';错误

使用Ace编辑器对子组件实例的native-element 进行Angular 获取时面临的问题

打字脚本中方括号符号属性访问和拾取实用程序的区别

使用RxJS from Event和@ViewChild vs KeyUp事件和RxJS主题更改输入字段值

如何根据查询结果重新排列日期

如何在AG-Grid文本字段中创建占位符

为什么NULL不能在构造函数的.Prototype中工作

为什么我不能使用其同级元素调用和更新子元素?

REACT-本机错误:错误类型错误:无法读取未定义的容器的属性

递归地将JSON对象的内容上移一级

正在发出错误的URL请求