angular6 组件间的交流方式 (2)-- viewChild 和 data service

原创
2018/07/30 10:45
阅读数 1.3K

我在上上篇文章中介绍了父子组件间通过 Input 和 Output 的交流方式。现在我会介绍组件间交流的其他两种方法,viewChild 和 data service。我将这篇文章分为两部分。首先看 viewChild 部分吧。

通过 viewChild 传递数据

什么是 viewChild?

viewChild 就是准许一个组件被注入到别的组件中。并且指明了该可用子组件有了通往父组件的通道。简单说来,就是如果我们想要子组件的特性,我们就可以使用 viewChild 这个神器。为了讲得详细点,以下面的代码为例。先创建两个组件,一个为父组件,另一个为子组件。 下面是 child.component.ts

import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
 counter :number = 0;
 IncreaseNumber():void{
  this.counter++;
}
  constructor() { }
  ngOnInit() {
  }
}

从这个代码块中,我们可以知道,该组件有一个 counter 属性和一个 IncreaseNumber 方法。每次调用 IncreaseNumber 方法,counter的值就会自增一次。现在我们看看父组件。 parent.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import{ChildComponent} from './child.component'
@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
  @ViewChild(ChildComponent) private childcomponent : ChildComponent;
Increase():void{
  this.childcomponent.IncreaseNumber();
}
Dicrease():void{
  this.childcomponent.counter--;
}
constructor() { }
  ngOnInit() {
  }
}

现在一步步分析上面的代码块。

  • import {ViewChild} from '@angular/core',再 import进子组件。

@ViewChild(ChildComponent) private childcomponent : ChildComponent;

这句代码非常重要,用于查询子组件,并在本地创建的子组件对象 childcomponent 中注入相同的属性。父组件同样有两个方法,自增和自减。父组件的模板可以改成这样子:

<p>
   <b>@ViewChild with Components..</b>
<br>
<br>
<input type="button" (click)="Increase()">
<input type="button" (click)="Decrease()">
<app-child></app-child>
</p>

可以看到,我们在父组件模板中实例化了子组件。

通过 data service 传递数据

到目前为止,我们已经知道了如何在相关组件间传递数据,那么如果是不想关的组件呢?我们通常会用 service 来实现数据传递。共享数据背后的思想是共享服务,他将所有被组件中用到的数据同步在一起。就像下面这个例子: 首先来个data service:Data.service.ts

import { Injectable } from '@angular/core';
import {BehaviorSubject} from 'rxjs'
@Injectable()
export class DataService {
    private messageSource = new BehaviorSubject < string > ("Start");
    constructor() {}
    changemessage(message: string): void {
        this.messageSource.next(message);
    }
}

现在我们来分析一下上面这个代码块:

  • import { Injectable } from '@angular/core' 引进 @Injectable 装饰器,这可以让其他组件和模块使用该服务类的功能。
  • import {BehaviorSubject} from 'rxjs' 这可以返回一种Observable类型,从而订阅不同类型的消息。这个 service 里面定义了一种changemessage(),它会返回从 Observable 那里获取到的数据。为了让各组件可以使用到这个服务,我们需要在根模块中将这个 service 以 provider:[DataService]的形式引入。 引入该服务的组件 service.component.ts
import { Component, OnInit } from '@angular/core';
import{DataService} from '../data.service';
@Component({
  selector: 'app-secondcomponent',
  templateUrl: './secondcomponent.component.html',
  styleUrls: ['./secondcomponent.component.css']
})
export class SecondcomponentComponent implements OnInit {
    childmessage: string = "";
    counter:number = 0;
    constructor(private data: DataService) {}
    ngOnInit() {
        this.data.currentmessage.subscribe(Message => this.childMessage);
    }
    newmessage(): void {
        this.data.changemessage("changing counter from sibling " + this.counter++);
    }
}

总结:

  1. 通过 @Injectable 装饰器添加 service;
  2. 使用 RxJs 中的 BehaviorSubject,返回数据为 Observable 类型;
  3. 订阅一些可变属性,在组件中给它重新赋值。

参考:https://dzone.com/articles/angular-component-communication-day-2

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部