Angular组件间通讯

组件树,1号是根组件AppComponent。

组件之间松耦合,组件之间知道的越少越好。

组件4里面点击按钮,触发组件5的初始化逻辑。

传统做法:在按钮4的点击事件里调用组件5的方法。紧密耦合。

Angular:在组件4根本不知道组件5存在的情况下实现。

使用松耦合的方式在组件之间传递数据开发出高重用性的组件。

使用输入输出属性在父子关系的组件之间传递数据。

一、输入输出属性概述

组件设计成黑盒模型,用输入属性声明从外部世界接收什么东西。不需要知道这些东西从哪里来来。

组件只需要知道当它需要的东西外部世界提供给它以后它应该怎么做。

组件通过输出属性发射事件告诉外部世界可能感兴趣的东西。至于事件发射给谁组件也不需要知道。

谁感兴趣谁自己订阅组件发射的事件。

二、输入属性

子组件定义了2个输入属性,被@Input()装饰器装饰的属性。

  @Input()
stockCode:string;
@Input()
amount:number;

父组件通过属性绑定到子组件输入属性的方式把stock属性绑定到子组件的stockCode属性上。

<div>
我是父组件
</div>
<div>
<input type="text" [(ngModel)]="stock" placeholder="请输入股票代码">
<app-order [stockCode]=stock [amount]="100"></app-order>
</div>

三、属性绑定是单向的,从父组件到子组件

每隔3s重置子组件的stockCode的值为Apple。

export class OrderComponent implements OnInit {

  @Input()
stockCode:string;
@Input()
amount:number; constructor() {
setInterval(()=>{
this.stockCode='Apple'
},3000)
} ngOnInit() {
}
}

当子组件的stockCode的值变为Apple的时候,父组件的stock的值并没有改变。说明绑定是单向的,只能是父组件改变子组件,子组件属性改变不会影响到父组件。

四,输出属性

Angular组件可以使用EventEmitter对象发射自定义事件,这些事件可以被其它组件处理。 EventEmitter是Rxjs中Subject类的一个子类,在响应式编程中,它既可以作为被观察者,也可以作为观察者。就是说EventEmitter对象即可以通过它的emit方法发射自定义事件,也可以通过subscribe方法来订阅EventEmitter发射出来的事件流。

如何使用EventEmit从组件内部向外发射事件?

例子场景:报价组件

假设需要一个组件,可以连接到股票交易所,并且实时的显示变动的股票价格,为了让这个组件可以在不同的金融类的应用中重用,除了实时显示股票价格,组件还应该将最新的股票价格发送到组件之外,这样其它的组件就可以针对变动的股票价格执行相应的业务逻辑。

Note:将特定的数据结构用类或接口来明确定义是一个良好的习惯

1、先模拟一个实时变动的IBM的股票价格

export class PriceQuoteComponent implements OnInit {

  //不连接股票服务,用一个随机数生成器模拟股票价格的变化,并将股票代码和最新的价格显示出来

  stockCode:string="IBM";
price:number; constructor() {
setInterval(()=>{
let priceQuote:PriceQuote=new PriceQuote(this.stockCode,100*Math.random());
this.price=priceQuote.lastPrice;
},1000)
} ngOnInit() {
} } //封装一个报价对象来封装股票价格信息
//将特定的数据结构用类或接口来明确定义是一个良好的习惯
export class PriceQuote {
constructor(public stockCode: string, //股票代码
public lastPrice: number //最新价格
) {
}
}

2、把信息输出出去,告诉组件外部,谁感兴趣谁来订阅

EventEmit后面的范型是要往出发射的事件的数据是什么类型的。

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

@Component({
selector: 'app-price-quote',
templateUrl: './price-quote.component.html',
styleUrls: ['./price-quote.component.css']
})
export class PriceQuoteComponent implements OnInit { //不连接股票服务,用一个随机数生成器模拟股票价格的变化,并将股票代码和最新的价格显示出来 stockCode: string = "IBM";
price: number; @Output() //发射事件需要写上Output
//EventEmitter需要一个范型
lastPrice: EventEmitter<PriceQuote> = new EventEmitter();
// constructor() {
setInterval(() => {
let priceQuote: PriceQuote = new PriceQuote(this.stockCode, 100 * Math.random());
this.price = priceQuote.lastPrice;
//用lastPrice emit一个值出去
this.lastPrice.emit(priceQuote);
}, 1000)
} ngOnInit() {
} }
//封装一个报价对象来封装股票价格信息
//将特定的数据结构用类或接口来明确定义是一个良好的习惯
export class PriceQuote {
constructor(public stockCode: string, //股票代码
public lastPrice: number //最新价格
) {
}
}

3、在父组件中接收报价信息并显示

父组件模版中通过事件绑定的方式来捕获并处理。

export class AppComponent {
stock = "";
priceQuote: PriceQuote = new PriceQuote("", 0); //event的类型就是子组件emit的时候发射出来的数据的类型
//父组件中通过event就可以拿到
priceQuoteHandler(event:PriceQuote){
this.priceQuote=event;
}
}

模版

<!--默认情况下,事件名字就是output输出属性的名字-->
<app-price-quote (lastPrice)="priceQuoteHandler($event)"></app-price-quote> <div>
这是在报价组件外部<br/>
股票代码是{{priceQuote.stockCode}},
股票价格是{{priceQuote.lastPrice | number:"2.0-2"}}
</div>

默认情况下,事件名字就是output输出属性的名字,可以改变事件名字,通过

  @Output("priceChange") //发射事件需要写上Output
//EventEmitter需要一个范型
lastPrice: EventEmitter<PriceQuote> = new EventEmitter();

模版中也改为

<app-price-quote (priceChange)="priceQuoteHandler($event)"></app-price-quote>

总结:通过输出属性发射事件,并通过事件携带数据,在父组件模版中通过事件绑定的方式来捕获并处理。

如果两个组件之间不存父子关系,如何以一种松耦合的方式来传递数据。此时需要使用中间人模式

本文作者starof,因知识本身在变化,作者也在不断学习成长,文章内容也不定时更新,为避免误导读者,方便追根溯源,请诸位转载注明出处:http://www.cnblogs.com/starof/p/8636579.html 有问题欢迎与我讨论,共同进步。

Angular组件——父子组件通讯的更多相关文章

  1. Angular中父子组件双向绑定传值

    下面为大家展示一个较为简单的ng父子组件双向绑定传值,下面是父组件页面 这个页面的大概功能就是父组件(红色)通过输入框输入内容反映到子组件上进行展示,并且进行了投影, 子组件(橙黄色)通过Input输 ...

  2. vue组件-构成组件-父子组件相互传递数据

    组件对于vue来说非常重要,学习学习了基础vue后,再回过头来把组件弄透! 一.概念 组件意味着协同工作,通常父子组件会是这样的关系:组件 A 在它的模版中使用了组件 B . 它们之间必然需要相互通信 ...

  3. Vuejs——(10)组件——父子组件通信

    版权声明:出处http://blog.csdn.net/qq20004604   目录(?)[+]   本篇资料来于官方文档: http://cn.vuejs.org/guide/components ...

  4. vue组件父子组件传递引用类型数据

    今天在写分页功能时,发现父子组件传值时,子组件监听不到父组件中数据的变化,传递的是一个引用类型的数据 其原因是引用类型共用一个内存地址,父子组件用的是同一个对象,故子组件监听不到变化,此时就需要做一个 ...

  5. Angular 非父子组件间的service数据通信

    完成思路:以service.ts(主题subject---订阅sbuscribe模式)为数据中转中间件,通过sku.ts的数据更改监测机制,同步更改service.ts中的数据,同时buy.ts组件实 ...

  6. vue全局组件-父子组件传值

    全局组件注册方式:Vue.component(组件名,{方法}) demo: 子组件:upload.vue <template> <div > <div class=&q ...

  7. vue组件父子组件之间传递数据

    举个栗子: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  8. React中父子组件数据传递

    Vue.js中父子组件数据传递:Props Down ,  Events Up Angular中父子组件数据传递:Props Down,  Events  Up React中父子组件数据传递:Prop ...

  9. React之父子组件之间传值

    1.新增知识点 /** React中的组件: 解决html 标签构建应用的不足. 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入. 父子组件:组件的相互调用中,我们把调 ...

随机推荐

  1. Mybatis认识

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .iB ...

  2. ajax的缺点

    平时我们大多注意的都是ajax给我们所带来的好处诸如用户体验的提升.对ajax所带来的缺陷有所忽视. 下面所阐述的ajax的缺陷都是它先天所产生的. 1.ajax干掉了back按钮,即对浏览器后退机制 ...

  3. javascript类型判断方法

    判断javascript中的类型,共有四种常用的方法 var a=6; var b="str"; var c=true; var arr=[]; typeof 用于基本类型的判断 ...

  4. NLP︱高级词向量表达(三)——WordRank(简述)

    如果说FastText的词向量在表达句子时候很在行的话,GloVe在多义词方面表现出色,那么wordRank在相似词寻找方面表现地不错. 其是通过Robust Ranking来进行词向量定义. 相关p ...

  5. REALTEK 刷机方法 法

    REALTEK 是通用板最多的IC 方案之一,什么常说的2025 2270 2023 2033 2525 2545 2660 2280 2662 2670 2672 2674  2661  2668 ...

  6. linux下ffmpeg安装

    1.ffmpeg下载地址: http://www.ffmpeg.org/download.html 2.解压 1 $ tar zvfj ffmpeg.tar.bz2 这里作者假设已经重命名为ffmpe ...

  7. Android View绘制回调方法流程

    Android中View的性命周期,挪用 invalidate() 战 requestLayout() 会触收哪些方式,一张图就可以讲解的很详细. 该图确切一看便特别很是清楚.让人简略的懂得View的 ...

  8. EFI、UEFI、MBR、GPT的区别

    UEFI.GPT.MBR是什么?这些专业术语不难理解,UEFI属于主板类名词,其作用类似于BIOS.GPT.MBR则属于硬盘类名词,它们的作用类似一艘航母的骨架,有了这个骨架,我们才可以进行细致到诸如 ...

  9. 如何注册Filter

    AX文件的一个对外接口DllRegisterServer,由外部调用,比如注册AX的时候:regsvr32 xxx.ax       通常情况下,我们的filter可能注册在"Direct ...

  10. Intel_CS_WebRTC 验证性测试

      机器: Centos 7.2 一.配置阿里云源 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/Cen ...