Search code examples
angulartypescriptangular2-componentsangular5typescript-decorator

Input vs Output Event Binding


I'm looking for an argument on why using @Output for events is better than passing an @Input function in Angular 2+.

Using @Input:

Parent Template:

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

Inside parent-component.ts:

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

Inside my-component.ts

@Input() customEventFunction: Function;

someFunctionThatTriggersTheEvent() {
  this.customEventFunction();
}

Using @Output:

Parent Template:

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

Inside parent-component.ts:

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

Inside my-component.ts

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

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

Both achieve the same goal, but I think that the @Output method is more typical from what I've seen in other Angular packages. One could argue that with an Input, you can check to see if the function exists if the event should only be triggered conditionally.

Thoughts?


Solution

  • The advantages of @Output event binding:

    1. Defining an event with @Output makes it clear that it expects callback methods to handle the event, using the standard Angular mechanism and syntax.
    2. Many event handlers can subscribe to the @Ouptut event. On the other hand, if you define an @Input property that accepts a callback function, only one event handler can be registered; assigning a second event handler would disconnect the first one. To make a parallel with standard DOM event handlers, the @Input callback function binding is similar to setting onmousemove="doSomething()" while the @Output event binding is more like calling btn.addEventListener("mousemove", ...).