9

I would like the child component value to be bound to the parent component. How to accomplish this when @Input() and [(ngModel)] are not enough ?

here is a plunker

Bellash
  • 5,719
  • 3
  • 39
  • 72
  • Do you mean you want to access child component methods and variables in parent component? – komron Nov 02 '17 at 11:04
  • In fact I would like the changes inside child component to affect the variable value in the parent. – Bellash Nov 02 '17 at 11:16
  • 1
    you can use a get set on your Input() https://stackoverflow.com/questions/36653678/angular2-input-to-a-property-with-get-set – Simon Lam Oct 03 '18 at 21:56

3 Answers3

11

Here you have to set @Output also and change the component like

export class CounterComponent {

  @Output('initoChange') emitter: EventEmitter<string> = new EventEmitter<string>();
  @Input('inito') set setInitoValue(value) {
      this.count = value;
  }
  count: number = 0;

  increment() {
    this.count++;
    this.emitter.emit(this.count);
  }

  decrement() {
    this.count--;
    this.emitter.emit(this.count);
  }

}

Here is the link to plunker , please have a look.

Vivek Doshi
  • 46,471
  • 9
  • 84
  • 100
  • Thanks a lot! You mean the `@Output` key must be (`'[var]Change'`) thus `'intoChange'`, right? – Bellash Nov 02 '17 at 11:40
  • Made a small change in the plunker [here](https://plnkr.co/edit/99qo5tzBkUAc0rZYAorQ?p=preview) Changes directly in the child component input are also rendered. – abhinav pandey Feb 09 '18 at 21:00
7

You can make two-way data binding like following:

@Component({

selector: 'app-sizer',
  template: `
  <div>
    <button (click)="dec()" title="smaller">-</button>
    <button (click)="inc()" title="bigger">+</button>
    <label [style.font-size.px]="size">FontSize: {{size}}px</label>
  </div>`
})
export class SizerComponent {
  @Input()  size: number | string;
  @Output() sizeChange = new EventEmitter<number>();

  dec() { this.resize(-1); }
  inc() { this.resize(+1); }

  resize(delta: number) {
    this.size = Math.min(40, Math.max(8, +this.size + delta));
    this.sizeChange.emit(this.size);
  }
}

And in template of parent component make two-way binding to size like following:

<app-sizer [(size)]="fontSizePx"></app-sizer>
<div [style.font-size.px]="fontSizePx">Resizable Text</div>

It (two-way binding) is just a syntax sugar for property binding, so it is equivalent to:

<app-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></app-sizer>

[(prop)] syntax using is possible when the prop has Input property called prop and event (Output property) that has a name propChange.

Code is from angular docs for more information navigate to this address: https://angular.io/guide/template-syntax#two-way-binding---

komron
  • 2,135
  • 2
  • 14
  • 26
  • using angular 6, I am getting the array of images from http request and pushing into array and displaying using ngfor . for the first set it works and after the page scroll dynamic fetching of images not working. Fetching of text is working dynamically on scroll also Can you help me . – Thilak Raj Jun 26 '18 at 05:07
0

use @Output() for example

@Output() event: EventEmitter<Type> = new EventEmitter();

send data via emit function

send(): void {
  this.event.emit(data);
}

read more about EventEmitter

Shailesh Ladumor
  • 5,968
  • 2
  • 35
  • 47