While doing a course on Udemy we have been allowing components to be passed data dy using the @Input()
decorator in the component class.
While reading through ngBook-2 I have found that there is another approach by using the input
property inside an @Component
decorator.
THIS similar question on SO, One person answered:
One advantage of using inputs is that users of the class only need to look at the configuration object passed to the @Component decorator to find the input (and output) properties.
and look through documentation state that:
Whether you use inputs/outputs or @Input/@Output the result is the same so choosing which one to use is largely a stylistic decision.
Really, the most useful information about this is mostly conflicting depending on where you look.
Inside @Component
@Component({
selector: 'product-image',
inputs: ['product'],
template: `
<img class="product-image" [src]="product.imageUrl">
})
class ProductImage {
product: Product;
}
Inside Class
@Component({
selector: 'product-image',
template: `
<img class="product-image" [src]="product.imageUrl">
})
class ProductImage {
@Input() product: Product;
}
Things I would like to know
@Input() and @Output() give a child component a way to communicate with its parent component. @Input() lets a parent component update data in the child component. Conversely, @Output() lets the child send data to a parent component.
The above pattern — passing data in through an “input” property and sending data out through an “output” event — is the primary way to share data between Angular 2 components.
Decorator that marks a class field as an input property and supplies configuration metadata. The input property is bound to a DOM property in the template. During change detection, Angular automatically updates the data property with the DOM property's value.
While Angular inputs/outputs should be used when sharing data to and from child components, ViewChild should be used when trying to utilize properties and methods of the child component directly in the parent component.
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.
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):
@Input
or @Output
, you can modify it a single place.I've personally used this style and really appreciate it helping keep the code DRY.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With