5

我正在寻找关于为什么使用@Output事件比@Input在 Angular 2+ 中传递函数更好的论点。

使用@Input

父模板:

<my-component [customEventFunction]=myFunction></my-component>

在 parent-component.ts 内部:

myFunction = () => {
  console.log("Hello world")
}

在 my-component.ts 里面

@Input() customEventFunction: Function;

someFunctionThatTriggersTheEvent() {
  this.customEventFunction();
}

使用@Output

父模板:

<my-component (onCustomEvent)=myFunction()></my-component>

在 parent-component.ts 内部:

myFunction() {
  console.log("Hello world")
}

在 my-component.ts 里面

@Output() onCustomEvent: EventEmitter<any> = new EventEmitter<any>();

someFunctionThatTriggersTheEvent() {
  this.onCustomEvent.emit();
}

两者都实现了相同的目标,但我认为该@Output方法比我在其他 Angular 包中看到的更典型。有人可能会争辩说,使用输入,您可以检查该函数是否存在,如果事件只应有条件地触发。

想法?

4

3 回答 3

3

@Output 事件绑定的优点:

  1. 使用 @Output 定义事件清楚地表明它期望回调方法使用标准的 Angular 机制和语法来处理事件。
  2. 许多事件处理程序可以订阅@Ouptut 事件。另一方面,如果定义一个接受回调函数的@Input 属性,则只能注册一个事件处理程序;分配第二个事件处理程序将断开第一个事件处理程序。为了与标准 DOM 事件处理程序并行,@Input 回调函数绑定类似于设置onmousemove="doSomething()",而@Output 事件绑定更像调用btn.addEventListener("mousemove", ...)
于 2017-12-19T17:10:58.990 回答
3

@Sajeetharan 的回答实际上并不完全正确:存在着的功能差异:执行上下文。考虑这种情况:

@Component({
  selector: 'app-example',
  template: `<button (click)="runFn()">Click Me</button>`,
})
export class ExampleComponent {
  @Input() public fn: any;

  public runFn(): void {
    this.fn();
  }
}

@Component({
  selector: 'app',
  template: `<app-example [fn]="myFn"></app-example>`,
})
export class AppComponent {
  public state = 42;

  // Using arrow syntax actually *will* alert "42" because
  // arrow functions do not have their own "this" context.
  //
  // public myFn = () => window.alert(this.state);

  public myFn(): void {
    // Oops, this will alert "undefined" because this function
    // is actually executed in the scope of the child component!
    window.alert(this.state);
  }
}

这实际上使得使用@Input()属性传递函数变得非常尴尬。至少它打破了最小惊喜的原则,并且可以引入鬼鬼祟祟的错误。

当然,在某些情况下,您可能不需要上下文。例如,也许您有一个可搜索的列表组件,它允许将复杂数据作为项目并需要传递一个fnEquals函数,以便搜索可以确定搜索输入文本是否与项目匹配。然而,这些情况通常可以通过更可组合的机制(内容投影等)更好地处理,从而提高可重用性。

于 2017-12-19T18:28:28.217 回答
2

功能上基本有no differences,但是

(i)当你使用时,@input你得到的好处@Input是我们可以定义类型以及它是私有的还是公共的

(ii) 正如@ConnorsFan评论中提到的,使用的优点@Ouput是许多订阅者可以处理输出事件,而只能为@Input属性提供一个处理程序。

于 2017-12-19T17:09:57.607 回答