runtimeZero
runtimeZero

Reputation: 28086

Understanding @input and @output in Angular2

For the example at url:

http://ngcourse.rangle.io/handout/components/app_structure/two_way_data_binding.html

I am unable to understand how the following two lines function with respect to @Output

//in app.component.ts
    (countChange)="number2=$event"
    (countChange)="onCountChanged($event)


//counter.component.ts
@Output() countChange: EventEmitter<number> = new EventEmitter<number>();

can someone help connect the dots here.

Upvotes: 2

Views: 3026

Answers (3)

Mike Gledhill
Mike Gledhill

Reputation: 29161

I actually think Angular's own examples on how @Input and @Output work are pretty poor.

Here is a simple StackBlitz example, which shows how it's done: https://angular-ivy-yqycev.stackblitz.io

It looks like this:

enter image description here

When you type in characters in the "transmitter" textbox, it'll send your string as an @Output... and the "receiver" will receive it via as an @Input, and show it in it's own textbox.

The key thing is that the "Transmitter" component will use an @Output...

transmitter.component.html:

<div>
  <h3>Transmitter</h3>
  <input type="text" [(ngModel)]="value" (ngModelChange)="onChange($event)" />
</div>

transmitter.component.ts:

  @Output() emitter = new EventEmitter<string>();

  onChange(event:any) {
    this.emitter.emit(this.value);
  }

And the "Receiver" component will use an @Input()...

receiver.component.html:

<div>
  <h3>Receiver</h3>
  <input type="text" [(ngModel)]="inputValue" />
</div>

receiver.component.ts:

  @Input() inputValue = "";

And, you can tie them together using this:

app.component.html:

  <app-transmitter (emitter)="onEmitter($event)"></app-transmitter>
  <app-receiver [inputValue]="currentValue"></app-receiver>

app.component.ts:

export class AppComponent  {

  currentValue = '';

  onEmitter(event:any) {
      console.log('Received: ' + event);
      this.currentValue = event;
  }
}

Hope this helps !

Upvotes: 1

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657356

this.countChange.emit('foo');

in counter.component.ts dispatches an event

(a bit similar to a click or other DOM event, but only handled in Angular internally)

(countChange)="onCountChanged($event)

registers a listener for this countChange event.
It might be a bit confusing because Angular uses the same binding syntax for @Output() as for DOM events.

When this.countChange.emit('foo'); is executed the registered event handler is called and 'foo' is passed (for the $event argument).

Upvotes: 1

micronyks
micronyks

Reputation: 55443

In simple terms,

To trigger custom events, EventEmitter is used (generally from childcmp to parentcmp). @Output is a way to declare custom event name (type of EventEmitter).

In your case it is (from counter.component.ts),

@Output() countChange: EventEmitter<number> = new EventEmitter<number>();

says countChange is a custom event (type of EventEmitter). EventEmitter has methods like emit(), next() which can emit values. So here it says countChange can emit number value. eg.

count=5;
buttonClick(){
    this.countChange.emit(this.count); // will emit 5 value 
}

Note whenever EventEmitter (here countChange) emits any (number) value, custom event(generally used in parentcmp) will be triggered by its own.

In your case it is (from app.component.ts),

(countChange)="number2=$event"  //number2=5; //countChange is a custom event

automatically this.count's 5 value will be received through $event and so it will be assigned to number2. which is also applicable for below code.

(countChange)="onCountChanged($event)  //countChange is a custom event

somewhere written in component.

onCountChanged(value)
 {
      console.log(value); // =5;
 }    

Upvotes: 1

Related Questions