如何在父组件和子组件之间进行双向数据流? (Angular 5)

时间:2018-04-04 20:21:05

标签: angular

我有一个简单的代码示例,我尝试从父组件数据发送到子组件,同时在数据更改时从子组件获取数据:

父:

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css']
})
export class ParentComponent {

  parentData:string = 'start value'

}
<app-child [childData]="parentData"></app-child>

子:

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent {

  @Input() childData: string;

}
<p>
    {{childData}}
    <br>
    <input [(ngModel)]="childData" type="text">
</p>

我需要为@Output()注释childData,但它已经使用@Input()进行了注释。 如何绑定变量childDataparentData

5 个答案:

答案 0 :(得分:4)

this article中所述:

  

要创建支持双向绑定的自己的组件,您必须这样做   定义@Output属性以匹配@Input,但后缀为   变化

您可以在this stackblitz中看到代码示例。

子组件:

<input [(ngModel)]="childData" type="text" (ngModelChange)="onModelChange($event)">
export class AppChildComponent {
  @Input() childData: string;
  @Output() childDataChange = new EventEmitter<string>();

  onModelChange(value: string) {
    this.childDataChange.emit(value);
  }
}

父组件:

<app-child [(childData)]="parentData"></app-child>

答案 1 :(得分:2)

要以与ngModel相同的方式启用双向数据绑定,您必须在子组件输入和输出中添加名称约为output name == input name + Change的两个属性。 父组件可以将其数据绑定到子组件,并且对于子组件中的每个更改,父组件都将更新

父html:

    <app-child[(childData)]="parentData"></app-child>

ChildComponent:

export class ChildComponent {

  @Input() childData: string;
  @Output() childDataChange = new EventEmitter<string>();

changeAction() {
this.childDataChange.emit("anything");
}
}

答案 2 :(得分:2)

我喜欢创建一个父和子都可以订阅和设置的服务。

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class ShareDataService {

  private subjectSharedData: Subject<any> = new Subject<any>();
  getSharedData$ = this.subjectSharedData.asObservable();

  setSharedData(data: any): void {
    this.subjectSharedData.next(data);
  }

}

在您需要传递数据的位置,您将服务方法调用setSharedData(data)数据,无论是子级还是父级。要检索的位置,请使用getSharedData$.subscribe(data => { console.log(data); })

您需要在app.module.ts或任何模块中导入此服务。然后在父组件和子组件的constructor方法中实例化它。

如果您有任何问题,请与我们联系。

答案 3 :(得分:1)

您可以轻松地将两者用于childData,它的工作方式与ngModel类似。 例如:

@Input()
@Output()
childData: string;


<app-child [(childData)]="parentData"></app-child>

答案 4 :(得分:1)

输出元素不必与输入具有相同的名称。输出变量应该是一个发射器,以便它将数据返回到绑定到ngModel。请参阅下面的代码段:

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

@Component({
  selector: 'app-voter',
  template: `
    <h4>{{name}}</h4>
    <button (click)="vote(true)"  [disabled]="voted">Agree</button>
    <button (click)="vote(false)" [disabled]="voted">Disagree</button>
  `
})
export class VoterComponent {
  @Input()  name: string;
  @Output() onVoted = new EventEmitter<boolean>();
  voted = false;

  vote(agreed: boolean) {
    this.onVoted.emit(agreed);
    this.voted = true;
  }
}

有关完整指南,请参阅以下链接: https://angular.io/guide/component-interaction