Angular父组件和子组件通过服务来通讯

我们在Angular中可以通过服务来实现子组件和父组件数据的双向流动。
在这里插入图片描述
这张图揭示了子组件和父组件通过服务来通讯的原理。
我们先用ng new parent-child来创建一个工程。接下来我们用以下命令生成相应的组件和服务。
生成父组件:
在这里插入图片描述
生成子组件:
在这里插入图片描述
生成服务:
在这里插入图片描述
整个工程的目录结构如下:
在这里插入图片描述
如果要让数据在多个组件中流动的话,我们就会想到多播,然后我们自然就会想到RxJS中的Subject对象。
共享服务parent.service.ts文件的代码如下:

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

@Injectable()
export class ParentService {
  // 数据源 next(发射数据)
  private parentToChildSource = new Subject<string>();
  private childToParentSource = new Subject<string>();

  // 数据流 subscribe(取得数据),在组件中需要订阅
  public parentToChild$ = this.parentToChildSource.asObservable();
  public childToParent$ = this.childToParentSource.asObservable();

  constructor() { }

  public parentToChild(parentDataItem: string) {
    this.parentToChildSource.next(parentDataItem);
  }

  public childToParent(childDataItem: string) {
    this.childToParentSource.next(childDataItem);
  }
}

父组件具体的代码如下:

import { Component, OnInit } from '@angular/core';
import { ParentService } from './parent.service';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css'],
  providers: [ParentService]
})
export class ParentComponent implements OnInit {
  /**
   * 父组件数据
   * @type {[string , string , string]}
   */
  public parentData = ['来自父组件数据a', '来自父组件数据b', '来自父组件数据c'];
  /**
   * 存储来自子组件数据
   * @type {Array}
   */
  public dataFromChild = [];
  public nextData = 0;
  constructor(private parentService: ParentService) {
    parentService.childToParent$.subscribe(data => {
      this.dataFromChild.push(`${data}`);
    });
  }

  ngOnInit() {
  }

  /**
   * 发射数据到子组件
   */
  public emissionDataToChild() {
    const toChildData = this.parentData[this.nextData++];
    this.parentService.parentToChild(toChildData);
    if (this.nextData >= this.parentData.length) { this.nextData = 0; }
  }

}

父组件模板的代码如下:

<p>
  <button (click)="emissionDataToChild()">发射数据给子组件</button>
</p>
<ul>
  <li *ngFor="let data of dataFromChild">{{data}}</li>
</ul>
<fieldset>
  <legend>子组件部分:</legend>
  <app-child></app-child>
</fieldset>

子组件具体的代码如下:

import { Component, OnDestroy } from '@angular/core';
import { ParentService } from '../parent/parent.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnDestroy {
  /**
   * 子组件的数据
   * @type {[string , string , string]}
   */
  public childData = ['来自子组件数据a', '来自子组件数据b', '来自子组件数据c'];
  /**
   * 存储来自父组件数据
   * @type {Array}
   */
  public dataFromParent = [];
  public nextData = 0;
  public subscription: Subscription;
  constructor(private parentService: ParentService) {
    this.subscription = parentService.parentToChild$.subscribe(data => {
      this.dataFromParent.push(`${data}`);
    });
  }

  /**
   * 发射数据到父组件
   */
  public emissionDataToParent() {
    const toParentData = this.childData[this.nextData++];
    this.parentService.childToParent(toParentData);
    if (this.nextData >= this.childData.length) { this.nextData = 0; }
  }

  public ngOnDestroy() {
    this.subscription.unsubscribe();
  }

}

子组件模板的代码如下:

<p>
  <button (click)="emissionDataToParent()">发射数据到父组件</button>
</p>
<ul>
  <li *ngFor="let data of dataFromParent">{{data}}</li>
</ul>

因为服务可以很方便的注入到其它的组件当中,又因为Subject对象可以将数据多播(传递)给订阅了这个对象的组件,因此结合Angular中的service和Rxjs中的Subject可以很方便的实现组件间的数据通讯。
最终代码大家可以到这里来下载:
父组件与子组件通过服务来通讯

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值