Angular 2/TypeScript: @Input/@output Or Input/output?


Answer :

Angular 2 Style Guide

According to the official Angular 2 style guide, STYLE 05-12 says

Do use @Input and @Output instead of the inputs and outputs properties of the @Directive and @Component decorators

The benefit is that (from the guide):

  • It is easier and more readable to identify which properties in a class are inputs or outputs.
  • If you ever need to rename the property or event name associated with @Input or @Output, you can modify it a single place.
  • The metadata declaration attached to the directive is shorter and thus more readable.
  • Placing the decorator on the same line makes for shorter code and still easily identifies the property as an input or output.

I've personally used this style and really appreciate it helping keep the code DRY.


One of the cool thing that I know you can do with decorators but I'm not if it's possible with the other way, is aliasing the variable:

export class MyComponent {   @Output('select') $onSelect = new EventEmitter<any>(); // this is aliased   @Output() finish  = new EventEmitter<any>(); // not aliased   sendUp(){     this.$onSelect.emit('selected');       this.finish.emit('done');  } } 

and then from outside :

 <my-component (select)="doSomething($event)"></my-component> 

The other one is setting a default value, you can set default value in both ways but decorators seem more convenient and less code.

@Component({    selector:'my-component' }) export class MyComponent {   @Input() id = 'default-id';         ngOnInit(){      console.log('id is : ',this.id); // will output default-id if you don't pass anything when using the component   } } 

So in this case , if the consumer doesn't pass the id as an input, you still have default-id ;

 <my-component></my-component>; 

Where as , if you wanted to do this with inputs array , you'd do :

@Component({    selector:'my-component',   inputs:['id'] }) export class MyComponent {   private id = 'default-id';         ngOnInit(){      console.log('id is : ',this.id); // will output default-id if you don't pass anything when using the component   } } 

The result is the same , but if you notice , in this case you have to put id both in inputs array and define it inside the class.

EDIT:

Apparently aliasing with outputs[] is also possible, like bellow :

@Component({   selector: 'my-component',   template: `    <button (click)="sendUp()">Send up</button>   `,   outputs: ['$onSelect: select'] }) export class ChildComponent {   $onSelect = new EventEmitter<any>(); // this is aliased    sendUp() {     this.$onSelect.emit('selected');   } } 

But again you have to define it in two places , on in the array and one in the class , so I'd still prefer the decorators.


Comments

Popular posts from this blog

Converting A String To Int In Groovy

"Cannot Create Cache Directory /home//.composer/cache/repo/https---packagist.org/, Or Directory Is Not Writable. Proceeding Without Cache"

Android How Can I Convert A String To A Editable