Marcin Król
Marcin Król

Reputation: 1654

How do I pass values from child component to parent component without explicitly using events?

Suppose I have two components, the parent A and a nested child B. I want to bind the aVal field of A to bVal field of B so that aVal is set to the value of bVal whenever bVal value changes. I know I can do it using EventEmitter and issuing an event whenever bVal changes but I do not want to explicitly care about events, I just want simple value binding. Is it even possible?

Parent component:

import {Component, Output} from "@angular/core";

@Component({
  selector: 'a',
  template: '<b></b>'
})
export class A {
  @Output() aVal: string;
}

Child component:

import {Component, Output} from "@angular/core";

@Component({
  selector: 'b',
  template: '<input [(ngModel)]="bVal"/>'
})
export class B {
  @Output() bVal: string;
}

I imagine the binding could look like <b (bVal)="aVal"></b> but it does not work.


UPDATE

I decided that the best I can do is the following. It is quite clear and lets me ignore dealing with events as much as possible.

Parent component:

import {Component, Output} from "@angular/core";

@Component({
  selector: 'a',
  template: '<b (bValChange)="aVal=b.bVal" #b></b>'
})
export class A {
  @Output() aVal: string;
}

Child component:

import {Component, Output, EventEmitter} from "@angular/core";

@Component({
  selector: 'b',
  template: '<input [(ngModel)]="bVal" (ngModelChange)="bValChange.emit()"/>'
})
export class B {
  bValChange: EventEmitter<void> = new EventEmitter<void>();
  bVal: string;
}

Upvotes: 1

Views: 2667

Answers (2)

Nate May
Nate May

Reputation: 4062

A service of some type (a factory makes sense) can be injected into both components and then bound to to a component variable. It's an expensive solution, but as I understand, Angular2 is built this way to prevent data in one modules/component from reaching data in others. This is for security and to ensure that unintended communication between components does not happen.

Also, the Output() Decorator can uses to emit an event with the desire value attached. here is a concise example

Upvotes: 2

Meir
Meir

Reputation: 14375

In A make the aVal a member (not an output)

aVal: string;

In B make the bVal and input:

@Input() bVal: string;

That should do it.

Btw, (bVal)="aVal" will not work. The (someChangeOutput)="handler($event)"` required a handler, and not a member/value

Upvotes: 1

Related Questions