简体   繁体   中英

Angular 4: How can I get the Parent Component's value to be updated by a changed value in a child Component without the Parent doing any extra work

I want to be able to accomplish an automatic update (2-way binding0 of a property that is in a parent controller from a child controller without the parent knowing that a @Output event needs to be passed into the child controller like I have in:

Plunker

App

import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'


@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
    </div>

    <div class="app">
      Parent: {{ myValue }}
      <myinput 
         [(zModel)]='myValue'
         (zChange)='valueChanged($event)'
      ></myinput> 
    </div>
  `,
})
export class App {
  name:string;
  constructor() {
    this.name = `Angular! v${VERSION.full}`
  }
  myValue: string = 'Hello World';
  valueChanged(event) {
    //alert('app: onchange (' + event + ")");
    this.myValue = event;
  }
}

MyinputComponent

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

@Component({
    selector: 'myinput',
    template: `
      <hr>
   <div >
        Inside Component: <u>{{ zModel }}</u> <br/><br/>
        <input type="text" 
            [(ngModel)]="zModel"
            (input)="valueChanged($event)"
            >
   </div>
  `
})
export class MyinputComponent {
    @Input() 
    zModel: string = '';

    @Output()
    zChange: EventEmitter<string> = new EventEmitter<string>();

  valueChanged(item){
    //alert('onchange (' + this.zModel + ')');
        this.zChange.emit(this.zModel);
    }
}

If by not doing any extra work , you mean that you want to remove the method valueChanged from the parent. If so, you are on the right track by marking the two-way binding:

[(zModel)]='myValue'

the only thing you need to change in the child to achieve this two-way-binding is to actually add the suffix Change to the exact name of your variable. So instead of

@Output()
zChange: EventEmitter<string> = new EventEmitter<string>();

it should be

@Output()
zModelChange: EventEmitter<string> = new EventEmitter<string>();

as your @Input is marked as zModel .

This also of course means that in the child valueChanged you need to mark the correct variable name:

valueChanged(item){
  this.zModelChange.emit(this.zModel);
}

So after these changes you can remove valueChanged from parent, and the child tag would just look like this:

<myinput [(zModel)]='myValue'></myinput> 

Here's your updated Plunker: http://plnkr.co/edit/eYx5wXnYauzqKXtduOvX?p=preview

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM