1 父组件和子组件之间的通讯

2 利用中间组件实现两个组件之间的通讯

3 利用服务实现两个组件之间的通讯

2017年8月26日20:09:13

  待更新...

1 组件之间的关系图

  1.1 父子关系

  1.2 兄弟关系

  1.3 没啥关系

  

2 组件之间有以下几种典型的通讯方案

  2.1 直接父子关系

    2.1.1 父组件直接访问子组件的 public 属性和方法

      技巧01:父组件的视图中调用子组件的方法需要利用模板变量

      技巧02:父组件的类中调用子组件的方法需利用@ViewChild装饰器

    2.1.2 借助于 @Input 和 @Output 进行通讯

      就是利用输入属性和输出属性来实现

      技巧01:输入属性和输出属性需要用到属性绑定和事件绑定相关的知识

  2.2 兄弟关系

    利用他们共同的父组件进行通信【有点麻烦】

    技巧01:此时他们的父组件相当于一个中间人

  2.3 适用于任何关系的方法

    2.3.1 借助于service单例进行通讯

    2.3.2 利用cookie或者localstorage进行通讯

    2.3.3 利用session进行通讯

3 直接调用

  对于父子组件而言,父组件可以直接调用子组件的public型属性和方法

  缺点:如果父组件直接访问子组件,那么两个组件之间的关系就被固定死了。父子两个组件紧密依赖,谁也离不开谁,也就都不能单独使用了。所以,除非你知道自己在做什么,最好不要直接在父组件里面直接访问子组件上的属性和方法,以免未来一改一大片。

  3.1 利用模板变量实现

    

  3.2 利用@ViewChild实现

    

  3.3 代码汇总

    》父组件

<div class="panel panel-primary">
<div class="panel-heading">父组件</div>
<div class="panel-body">
<child #child1 ></child>
<p>
<label>获取子组件的info属性值为:</label>
<span>{{child1.info}}</span>
</p>
<p>
<button (click)="child1.greeting('王杨帅');">调用子组件的greeting方法</button>
</p>
</div>
<div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
</div>

HTML

import { Component, OnInit, ViewChild } from '@angular/core';
import { ChildComponent } from './child/child.component';
import { AfterViewInit, AfterContentChecked, AfterContentInit, AfterViewChecked } from '@angular/core/src/metadata/lifecycle_hooks'; @Component({
selector: 'parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.scss']
})
export class ParentComponent implements OnInit { @ViewChild("child1")
child1 : ChildComponent; currentDate : Date; constructor() { } ngOnInit() {
this.currentDate = new Date();
// setInterval(() => {
// this.currentDate = new Date();
// }, 1000); this.child1.greeting("三少");
} }

TS

    》子组件

<div class="panel panel-primary">
<div class="panel-heading">子组件</div>
<div class="panel-body"> </div>
<div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
</div>

HTML

import { Component, OnInit, DoCheck,AfterViewChecked, EventEmitter, AfterContentInit, Output, Input, OnChanges, SimpleChanges, AfterViewInit, AfterContentChecked } from '@angular/core';

@Component({
selector: 'child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.scss']
})
export class ChildComponent implements OnInit { currentDate : Date; info : string; constructor() { } ngOnInit() {
this.info = "子组件中的info属性";
this.currentDate = new Date();
// setInterval(() => {
// this.currentDate = new Date();
// }, 1000);
} greeting(name : string) : void {
alert("子组件中greeting方法的返回值: Helo " + name);
console.log("子组件中greeting方法的返回值: Helo " + name);
} }

TS

4 @Input 和 @Output

  就是通过属性绑定来实现父组件向子组件的输入属性船值;通过事件绑定来实现子组件向父组件传值

  技巧01:其实可以直接利用双向绑定来实现

  4.1 父组件向子组件传值

    子组件利用@Input定义一个输入属性,父组件视图中在子组件的标签上利用属性绑定来实现

  4.2 子组件向父组件传值

    子组件利用@Output定义一个输出属性,父组件视图中在子组件标签上利用事件来实现

  4.3 代码汇总

    》父组件

<div class="panel panel-primary">
<div class="panel-heading">父组件</div>
<div class="panel-body"> <!-- 这三种写法都可以实现 -->
<!-- <child [info]="parentInfo" (infoChange)="onInfoChange($event)" ></child> -->
<!-- <child [info]="parentInfo" (infoChange)="parentInfo=$event" ></child> -->
<child [(info)]="parentInfo" ></child> <p>
{{parentInfo}}
</p>
</div>
<div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
</div>

HTML

import { Component, OnInit, ViewChild } from '@angular/core';
import { ChildComponent } from './child/child.component';
import { AfterViewInit, AfterContentChecked, AfterContentInit, AfterViewChecked } from '@angular/core/src/metadata/lifecycle_hooks'; @Component({
selector: 'parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.scss']
})
export class ParentComponent implements OnInit { parentInfo : string; currentDate : Date; constructor() { } ngOnInit() {
this.parentInfo = "王杨帅";
this.currentDate = new Date();
// setInterval(() => {
// this.currentDate = new Date();
// }, 1000);
} onInfoChange(info : string) {
this.parentInfo = info;
} }

TS

    》子组件

<div class="panel panel-primary">
<div class="panel-heading">子组件</div>
<div class="panel-body">
<p>
输入属性info的值为:{{info}}
</p>
<p>
<button (click)="onTest()" >点击向父组件发送数据</button>
</p>
</div>
<div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
</div>

HTML

import { Component, OnInit, DoCheck,AfterViewChecked, EventEmitter, AfterContentInit, Output, Input, OnChanges, SimpleChanges, AfterViewInit, AfterContentChecked } from '@angular/core';

@Component({
selector: 'child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.scss']
})
export class ChildComponent implements OnInit { currentDate : Date; @Input()
info : string; @Output()
infoChange : EventEmitter<string> = new EventEmitter(); constructor() { } ngOnInit() {
this.currentDate = new Date();
// setInterval(() => {
// this.currentDate = new Date();
// }, 1000);
} onTest() : void {
this.infoChange.emit("子组件传过来的数据");
} }

TS

5 服务实现

  待更新...

6 cookie或localstorage实现

  6.1 原理图

    

  6.2 代码汇总

    》工具组件

      利用投影来简化代码

<div class="panel panel-primary">
<div class="panel-heading">
<ng-content select=".heading"></ng-content>
</div>
<div class="panel-body">
<ng-content select=".body"></ng-content>
</div>
<div class="panel-footer">
{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}
</div>
</div>

HTML

import { Component, OnInit } from '@angular/core';
import { setInterval } from 'timers'; @Component({
selector: 'panel',
templateUrl: './panel.component.html',
styleUrls: ['./panel.component.scss']
})
export class PanelComponent implements OnInit { currentDate : Date; constructor() { } ngOnInit() {
this.currentDate = new Date();
setInterval(() => {
this.currentDate = new Date();
}, 1000);
} }

TS

    》测试组件01

<panel>
<div class="heading">
测试组件01
</div>
<div class="body">
<button (click)="onClick()">写入数据到</button>
</div>
</panel>

HTML

import { Component, OnInit } from '@angular/core';
import { TestService } from '../services/test.service'; @Component({
selector: 'test01',
templateUrl: './test01.component.html',
styleUrls: ['./test01.component.scss']
})
export class Test01Component implements OnInit { constructor(
) { } ngOnInit() {
} onClick() : void {
// 将对象转化成JSON字符串并存储道浏览器缓存中
window.localStorage.setItem("user", JSON.stringify({name: "王杨帅", age: 9}));
} }

TS

    》测试组件02

<panel>
<div class="heading">
测试组件02
</div>
<div class="body">
<p>
<button (click)="onClick()">获取数据</button>
</p>
</div>
</panel>

HTML

import { Component, OnInit } from '@angular/core';
import { TestService } from '../services/test.service'; @Component({
selector: 'test02',
templateUrl: './test02.component.html',
styleUrls: ['./test02.component.scss']
})
export class Test02Component implements OnInit { constructor(
) { } ngOnInit() {
} onClick() : void {
// 从浏览器缓存中获取数据【PS: 获取到的是string类型的数据】
let data = localStorage.getItem("user");
console.log(data); // 将JSON字符串转化成对象
let json_data = JSON.parse(data); console.log(json_data.name);
window.localStorage.removeItem("user");
} }

TS

7 session实现

  待更新...

Angular10 组件之间的通讯的更多相关文章

  1. 组件之间的通讯:vuex状态管理,state,getters,mutations,actons的简单使用(一)

    之前的文章中讲过,组件之间的通讯我们可以用$children.$parent.$refs.props.data... 但问题来了,假如项目特别大,组件之间的通讯可能会变得十分复杂... 这个时候了我们 ...

  2. vue.js组件之间的通讯-----父亲向儿子传递数据,儿子接收父亲的数据

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. angular组件之间的通讯

    组件通讯,意在不同的指令和组件之间共享信息.如何在两个多个组件之间共享信息呢. 最近在项目上,组件跟组件之间可能是父子关系,兄弟关系,爷孙关系都有.....我也找找了很多关于组件之间通讯的方法,不同的 ...

  4. Vue父子组件之间的通讯(学习笔记)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Angular组件之间通讯

    组件之间会有下列3种关系: 1. 父子关系 2. 兄弟关系 3. 没有直接关系 通常采用下列方式处理(某些方式是框架特有)组件间的通讯,如下: 1父子组件之间的交互(@Input/@Output/模板 ...

  6. Angular 发布订阅模式实现不同组件之间通讯

    在我们项目中要实现不同组件之间通讯,Angular的@Input和@Output只能实现有父子组件的限制,如果是复杂跨组件实现不同组件可以通过共享变量的方式实现,比如这个博客的思路:https://w ...

  7. vue组件的基本使用,以及组件之间的基本传值方式

    组件(页面上的每一个部分都是组件) 1.三部分:结构(template),样式(style),逻辑(script) 2.组件的作用:复用 3.模块包含组件 4.组件创建:     1.全局组件:Vue ...

  8. Angular学习笔记之组件之间的交互

    1.@Input:可设置属性 当它通过属性绑定的形式被绑定时,值会“流入”这个属性. 在子组件中使用,例如:@Input()name:string 父组件定义宾亮,并在父组件的模板中绑定,例如: 子组 ...

  9. React组件间的通讯

    组件化开发应该是React核心功能之一,组件之间的通讯也是我们做React开发必要掌握的技能.接下来我们将从组件之间的关系来分解组件间如何传递数据. 1.父组件向子组件传递数据 通讯是单向的,数据必须 ...

随机推荐

  1. day 5 模块导入、常用模块os shutil sys commands subprocess hashlib json pickle zipfile traceback random datetime

    os: os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录:相当于shell下cd os. ...

  2. 登陆获取shell时的配置文件加载过程

    最近遇到一台ubuntu服务器登陆时默认语言环境变量变成posix问题, 导致中文显示乱码,影响程序的正常运行 # locale LANG= LANGUAGE= LC_CTYPE="POSI ...

  3. LINQ 学习路程 -- 查询操作 ElementAt, ElementAtOrDefault

    Element Operators (Methods) Description ElementAt 返回指定索引的元素,如果索引超过集合长度,则抛出异常 ElementAtOrDefault 返回指定 ...

  4. DL三(向量化编程 Vectorized implementation)

    向量化编程实现 Vectorized implementation 一向量化编程 Vectorization 1.1 基本术语 向量化 vectorization 1.2 向量化编程(Vectoriz ...

  5. Jquery Uploadify多文件上传实例

    jQuery Uploadify开发使用的语言是java. 详细的相关文档,可以参考官网的doc:http://www.uploadify.com/documentation/ 官网的讲解还是很详细的 ...

  6. CSS: iPhone Custom CSS

    1. [代码][CSS]代码 <style type="text/css" media="screen"> /* iPhone 4@media on ...

  7. R语言矩阵运算

    R语言矩阵运算 主要包括以下内容:创建矩阵向量:矩阵加减,乘积:矩阵的逆:行列式的值:特征值与特征向量:QR分解:奇异值分解:广义逆:backsolve与fowardsolve函数:取矩阵的上下三角元 ...

  8. java:maven中webapp下的jsp不能访问web-inf下面的bean

    java:maven中webapp下的jsp不能访问web-inf下面的bean 当然 WEB-INF下面的文件是不能访问的,只能吧jsp文件放入到WEB-INF下面,然后通过配置WEB-INF下we ...

  9. python ddt 重写

    对此方法重写 def mk_test_name(name, value, index=0): 重写前 index = "{0:0{1}}".format(index + 1, in ...

  10. Python基础-操作mysql

    mysql 属于第三方模块,需要先安装 pip install pymysql,sql执行后,数据获取函数有三种cur.fetchone()#获取第一条数据,依次类推下去,第二次执行时候,就会取除去第 ...