文档章节

Angular组件交互的3种方式

我是钟钟
 我是钟钟
发布于 2017/08/29 13:51
字数 836
阅读 126
收藏 0

原文地址:https://medium.com/@mirokoczka/3-ways-to-communicate-between-angular-components-a1e3f3304ecb

输入图片说明

本文是为Angular 2+编写的。在撰写本文时,最新版本是Angular 4。

这篇文章为初学者编写的,如果您是高级的或中级的Angular开发人员,您可能已经了解所有这些技术。

组件之间如何通信?这是我看到许多初级的Angular开发者争论的话题。我将向您展示3种最常见的方法,其中包含适合不同用例的示例。redux的方式,我会在以后另外写一篇文章。

<!-- more -->

输入图片说明

想象一下你的应用程序中有侧边栏的用例。侧边栏打开或关闭。你会拥有一个侧边栏组件,然后具有打开/关闭的功能以及询问组件状态的方法。

我将介绍三种实现这一行为的方法:

  • 将一个组件的引用传递给另一个组件
  • 通过父组件进行通信
  • 通过服务通信

这篇文章中的所有实例在StackBlitz和github仓库都有对应的源代码。

将一个组件的引用传递给另一个组件

当组件之间有依赖关系时,应使用此解决方案。例如下拉菜单,下拉菜单切换(按钮)。它们通常不能独立存在。

Demo

Github

我们将创建一个side-bar-toggle组件,它将side-bar作为输入属性,通过点击切换按钮,打开或关闭side-bar。

以下是相关的代码:

app.component.html


<app-side-bar-toggle [sideBar]="sideBar"></app-side-bar-toggle>
<app-side-bar #sideBar></app-side-bar>

side-bar-toggle.component.ts

@Component({
  selector: './app-side-bar-toggle',
  templateUrl: './side-bar-toggle.component.html',
  styleUrls: ['./side-bar-toggle.component.css']
})
export class SideBarToggleComponent {

  @Input() sideBar: SideBarComponent;

  @HostListener('click')
  click() {
    this.sideBar.toggle();
  }

}

side-bar.component.ts

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

  @HostBinding('class.is-open')
  isOpen = false;

  toggle() {
    this.isOpen = !this.isOpen;
  }

}

通过父组件进行通信

可以通过父组件来控制组件之间的共享状态,以为你不想因为一个变量创建新的服务或者编写样板代码。

Demo Github

这种方法的实现与前一种方法几乎相同,但是side-bar-toggle组件不接收side-bar作为输入。而父组件则保留传递给side-bar组件的sideBarIsOpened属性。

app.component.html

<app-side-bar-toggle (toggle)="toggleSideBar()"></app-side-bar-toggle>
<app-side-bar [isOpen]="sideBarIsOpened"></app-side-bar>

app.component.ts

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent {
  sideBarIsOpened = false;

  toggleSideBar(shouldOpen: boolean) {
    this.sideBarIsOpened = !this.sideBarIsOpened;
  }
}

side-bar-toggle.component.ts

@Component({
  selector: './app-side-bar-toggle',
  templateUrl: './side-bar-toggle.component.html',
  styleUrls: ['./side-bar-toggle.component.css']
})
export class SideBarToggleComponent {

  @Output() toggle: EventEmitter<null> = new EventEmitter();

  @HostListener('click')
  click() {
    this.toggle.emit();
  }

}

side-bar.component.ts

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

  @HostBinding('class.is-open') @Input()
  isOpen = false;

}

通过服务通信

最后这种方式在你需要处理受控组件或者从多个组件中提取状态的时候是非常有效的一种方式。

Demo Github

输入图片说明

现在我们在应用程序中有多个地方需要访问我们的side-bar组件。我们来看看我们怎么做。

我们现在将创建side-bar.service.ts,我们有:

  • side-bar.service.ts
  • side-bar.component.ts
  • side-bar.component.html

side-bar服务将具有toggle方法和change事件,因此,当side-bar组件的状态更改的时候,可以通知每一个注入了此服务的组件。

在这个例子中,side-bar-toggle组件和side-bar组件都没有输入属性,因为它们通过服务进行通信。

现在的代码:

app.component.html

<app-side-bar-toggle></app-side-bar-toggle>
<app-side-bar></app-side-bar>

app.component.ts

@Component({
  selector: './app-side-bar-toggle',
  templateUrl: './side-bar-toggle.component.html',
  styleUrls: ['./side-bar-toggle.component.css']
})
export class SideBarToggleComponent {

  constructor(
    private sideBarService: SideBarService
  ) { }

  @HostListener('click')
  click() {
    this.sideBarService.toggle();
  }
}

side-bar.component.ts

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

  @HostBinding('class.is-open')
  isOpen = false;

  constructor(
    private sideBarService: SideBarService
  ) { }

  ngOnInit() {
    this.sideBarService.change.subscribe(isOpen => {
      this.isOpen = isOpen;
    });
  }
}

side-bar.service.ts

@Injectable()
export class SideBarService {

  isOpen = false;

  @Output() change: EventEmitter<boolean> = new EventEmitter();

  toggle() {
    this.isOpen = !this.isOpen;
    this.change.emit(this.isOpen);
  }

}

© 著作权归作者所有

共有 人打赏支持
我是钟钟
粉丝 52
博文 43
码字总数 40311
作品 1
深圳
高级程序员
【前端】Angular组件钩子

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m18633778874/article/details/82259409 Angular中的钩子方法,是非常常用的知识点,也在项目代码运用中有所体...

冯浩月
08/31
0
0
【前端】—聊聊我认识的Angular

前言 最近接触的项目前端用到了Angular框架,之前略有耳闻,从vue换到Angular,感觉东西差不多,还是要系统学习的,先来了解下。 正文 1、Angular 的发展 AngularJS 是一款来自Google的前端J...

zt15732625878
05/19
0
0
关于AngularJS中的ng-class

在前面Angularjs开发一些经验总结中我们说到在angular开发中angular controller never 包含DOM元素(html/css),在controller需要一个简单的POJO(plain object javascript object),与vie...

顽Shi
2014/06/09
0
1
使用Yeoman快速构建基于angular的web应用

前言 最近在学习使用安哥拉(angular.js)编写web应用,看了一些网友实践了解到yeoman,这个工具实在太好用了,必须在这里介绍一下。 angular 首先简单介绍一下angular,它是由google开源的一套...

snakelxc
2013/08/25
0
0
使用Yeoman快速构建基于angular的web应用

前言 最近在学习使用安哥拉(angular.js)编写web应用,看了一些网友实践了解到yeoman,这个工具实在太好用了,必须在这里介绍一下。 angular 首先简单介绍一下angular,它是由google开源的一套...

kisops
2013/08/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

992. Sort Array By Parity II - LeetCode

Question 992. Sort Array By Parity II Solution 题目大意:给一个int数组,一半是奇数一半是偶数,分别对偶数数和奇数数排序并要求这个数本身是偶数要放在偶数位上 思路:把奇数数和偶数数...

yysue
24分钟前
1
0
Snackbar源码分析

目录介绍 1.最简单创造方法 1.1 Snackbar作用 1.2 最简单的创建 1.3 Snackbar消失的几种方式 2.源码分析 2.1 Snackbar的make方法源码分析 2.2 对Snackbar属性进行设置 2.3 Snackbar的show显示...

潇湘剑雨
56分钟前
1
0
分布式作业系统 Elastic-Job-Lite 源码分析 —— 作业数据存储

分布式作业系统 Elastic-Job-Lite 源码分析 —— 作业数据存储 摘要: 原创出处 http://www.iocoder.cn/Elastic-Job/job-storage/ 本文基于 Elastic-Job V2.1.5 版本分享 1. 概述 本文主要分享...

DemonsI
今天
1
0
jmockit demo

1、@Mocked,标识一个指定的class的实例或被测对象的参数被Mock掉。 2、@Capturing,标识一个被Mock的对象,从该对象派生的子类也被Mock了。 3、@Injectable,标识只有一个指定的被测对象的内...

我的老腰啊
今天
1
0
内容换行

用 <textarea>13611112222 这里想换行 13877779999</textarea><textarea>13611112222 13877779999</textarea>...

小黄狗
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部