文档章节

Angular组件交互的3种方式

我是钟钟
 我是钟钟
发布于 2017/08/29 13:51
字数 836
阅读 103
收藏 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

前言 最近接触的项目前端用到了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
5个示例带你学习AngularJS

本文由 伯乐在线 - 蝈蝈 翻译自 tutorialzine。欢迎加入技术翻译小组。转载请参见文章末尾处的要求。 直到现在,你或许已经听说过AngularJS了,一个改变你对web应用思考方式,由谷歌开发的令...

冬瓜1
2013/12/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

文件的压缩与解压(linux)

Linux下*.tar.gz文件解压缩命令 1.压缩命令:   命令格式:tar -zcvf 压缩后文件名.tar.gz 被压缩文件名 可先切换到当前目录下。压缩文件名和被压缩文件名都可加入路径。 2.解压缩命令: ...

qimh
27分钟前
1
0
invalid character found in the request target 异常

这个异常时因为Tomcat 9不支持请求格式出现“{”等非法字符的问题 因为tomcat版本问题遇到的坑,记录一下。 问题 今天由于要测试一下订单详情页的异步查询,在本地起了一个服务,发送的请求是...

edwardGe
32分钟前
3
0
发现抓包软件fiddler的bug

1个请求他跳转之后,直接400,被拦在了Apache,使用fiddler 的,replay requests 是同样的结果,但是replay composer确是正常的。 也就是说这replay requests 是发原来的包,replay composer...

NLGBZJ
42分钟前
1
0
linux screen 命令详解

shell关闭后, 主机仍然运行 screen命令 启动jenkins以后, screen, 然后按ctrl+a 再按d 这样暂停了子界面, 这时候回到了父界面 用screen –ls查看目前子界面的状态 [root@free /]# screen -l...

SuShine
43分钟前
2
0
mac机器切换无线网络导致网页不能打开的问题

问题: 公司和家里使用不同的WI-FI,每次从家到公司时自动切换网络后,公司的许多地址不能访问, ping域名是可以ping同的,但是网页却打不开... 问题分析: 初步猜想是DNS缓存的问题? 对于MAC系统没...

Lennie002
45分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部