13

I am pondering this issue and can't find any explanation.

When passing parameters to a Component in Angular2

Given

<my-component [attr]="someModelVariable"></my-component>

There seems to be two ways of accepting the attr bound value:

@Component{(
    selector: "my-component",
    inputs: ["attr"]
)}
export class MyComponent {
}

Or you do this:

@Component{(
    selector: "my-component"
)}
export class MyComponent {
    @Input()
    public attr: any;
}

And I have actually seen code that uses both at the same time, Can someone explain what the differences between them are?

/Rickard

Rickard Staaf
  • 2,650
  • 2
  • 14
  • 14
  • 6
    There are no differences, [`@Component()`](https://github.com/angular/angular/issues/5036#issuecomment-152789185) is the canonical place. Remember too that there are users writing in plain ES5 (not using TypeScript), so they need a way to write without decorators. – Eric Martinez Nov 11 '15 at 11:01

3 Answers3

8

Although Eric already provided the answer in the comments, I'll add my 2 cents.

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.

One advantage of using @Input is that we can define the type and whether it is private or public:

@Input() public attr: string;

Note that the style guide recommends using @Input:

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

Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
  • The last thing can be done with inputs too, since you can do: `@Component{( selector: "my-component", inputs: ["attr"] )} export class MyComponent { public attr: string; }` – Rickard Staaf Dec 28 '15 at 09:05
  • @RickardStaaf, good point. However, this is less DRY, as we have to repeat `attr` in two places. – Mark Rajcok Dec 28 '15 at 14:23
  • `@Input( bindingPropertyName: string )` decorator also has a parameter. It can be used to create an alias. – Irshad Jun 08 '19 at 15:45
1

It is true that @Input allows easy definition of type, scope and default values, but the availability of getters and setters means that the functionality is effectively the same with both techniques.

I'm not about to suggest using inputs over @Input, and I agree with the other posters that it is best to stick to the current style guide, but I did find it a useful exercise to compare the two approaches when I came across them myself.

Below is a fuller comparison also using getters and setters to hopefully demonstrate the differences in layout and similarities in behaviour.

Using inputs

@Component({
    selector: 'my-component',
    template: '<h2>Value = {{ attr }}</h2>',
    inputs: ['attr']
})
export class MyComponent {

  public _attr: string;

  set attr(value) : void {
    console.log(`setter: ${value}`);
    this._attr = value;
  }

  get attr() : string {
    console.log(`getter: ${this._attr}`);
    return this._attr;
  }
}

And using @Input:

@Component({
    selector: 'my-component',
    template: '<h2>Value = {{ attr }}</h2>'
})
export class MyComponent {

  public _attr: string;

  @Input()
  set attr(value: string) : void {
    console.log(`setter: ${value}`);
    this._attr = value;
  }
  get attr() : string {
    console.log(`getter: ${this._attr}`);
    return this._attr;
  }
}
Jason
  • 2,271
  • 2
  • 24
  • 23
0

Another quick tip - using inputs instead of the @input decorator while using typescript might fail your build as it won't recognise the variables that you defined in the @components decorator. silly but annoying... thats why i got here in the first place.

i'm also recommending to stick with the on-going style guide that recommends using the @input

Ben Yitzhaki
  • 1,376
  • 16
  • 31