资讯专栏INFORMATION COLUMN

angular 组件通信

cikenerd / 665人阅读

摘要:单页面应用组件通信有以下几种,这篇文章主要讲通信父组件子组件子组件父组件组件组件父组件子组件子组件父组件本质上还是注入父组件不推荐使用局部变量的的的上面图表总结了能用到通信方案期中最后种是通用的的组件之间都可以使用这种其中是最最牛逼的用法甩

单页面应用组件通信有以下几种,这篇文章主要讲 Angular 通信

父组件 => 子组件

子组件 => 父组件

组件A = > 组件B

父组件 => 子组件 子组件 => 父组件 sibling => sibling
@input @output
setters (本质上还是@input) 注入父组件
ngOnChanges() (不推荐使用)
局部变量
@ViewChild()
service service service
Rxjs的Observalbe Rxjs的Observalbe Rxjs的Observalbe
localStorage,sessionStorage localStorage,sessionStorage localStorage,sessionStorage

上面图表总结了能用到通信方案,期中最后3种,是通用的,angular的组件之间都可以使用这3种,其中Rxjs是最最牛逼的用法,甩redux,promise,这些同样基于函数式的状态管理几条街,下面一一说来

父组件 => 子组件 @input,最常用的一种方式

</>复制代码

  1. @Component({
  2. selector: "app-parent",
  3. template: "
    childText:
    ",
  4. styleUrls: ["./parent.component.css"]
  5. })
  6. export class ParentComponent implements OnInit {
  7. varString: string;
  8. constructor() { }
  9. ngOnInit() {
  10. this.varString = "从父组件传过来的" ;
  11. }
  12. }

</>复制代码

  1. import { Component, OnInit, Input } from "@angular/core";
  2. @Component({
  3. selector: "app-child",
  4. template: "

    {{textContent}}

    ",
  5. styleUrls: ["./child.component.css"]
  6. })
  7. export class ChildComponent implements OnInit {
  8. @Input() public textContent: string ;
  9. constructor() { }
  10. ngOnInit() {
  11. }
  12. }
setter

setter 是拦截@input 属性,因为我们在组件通信的时候,常常需要对输入的属性处理下,就需要setter了,setter和getter常配套使用,稍微修改下上面的child.component.ts
child.component.ts

</>复制代码

  1. import { Component, OnInit, Input } from "@angular/core";
  2. @Component({
  3. selector: "app-child",
  4. template: "

    {{textContent}}

    ",
  5. styleUrls: ["./child.component.css"]
  6. })
  7. export class ChildComponent implements OnInit {
  8. _textContent:string;
  9. @Input()
  10. set textContent(text: string){
  11. this._textContent = !text: "啥都没有给我" ? text ;
  12. } ;
  13. get textContent(){
  14. return this._textContent;
  15. }
  16. constructor() { }
  17. ngOnInit() {
  18. }
  19. }
onChange

这个是通过angular生命周期钩子来检测,不推荐使用,要使用的话可以参angular文档

@ViewChild()

@ViewChild() 一般用在调用子组件非私有的方法

</>复制代码

  1. import {Component, OnInit, ViewChild} from "@angular/core";
  2. import {ViewChildChildComponent} from "../view-child-child/view-child-child.component";
  3. @Component({
  4. selector: "app-parent",
  5. templateUrl: "./parent.component.html",
  6. styleUrls: ["./parent.component.css"]
  7. })
  8. export class ParentComponent implements OnInit {
  9. varString: string;
  10. @ViewChild(ViewChildChildComponent)
  11. viewChildChildComponent: ViewChildChildComponent;
  12. constructor() { }
  13. ngOnInit() {
  14. this.varString = "从父组件传过来的" ;
  15. }
  16. clickEvent(clickEvent: any) {
  17. console.log(clickEvent);
  18. this.viewChildChildComponent.myName(clickEvent.value);
  19. }
  20. }

</>复制代码

  1. import { Component, OnInit } from "@angular/core";
  2. @Component({
  3. selector: "app-view-child-child",
  4. templateUrl: "./view-child-child.component.html",
  5. styleUrls: ["./view-child-child.component.css"]
  6. })
  7. export class ViewChildChildComponent implements OnInit {
  8. constructor() { }
  9. name: string;
  10. myName(name: string) {
  11. console.log(name);
  12. this.name = name ;
  13. }
  14. ngOnInit() {
  15. }
  16. }
局部变量

局部变量和viewChild类似,只能用在html模板里,修改parent.component.html,通过#viewChild这个变量来表示子组件,就能调用子组件的方法了.

</>复制代码

child 组件如下

</>复制代码

  1. @Component({
  2. selector: "app-view-child-child",
  3. templateUrl: "./view-child-child.component.html",
  4. styleUrls: ["./view-child-child.component.css"]
  5. })
  6. export class ViewChildChildComponent implements OnInit {
  7. constructor() { }
  8. name: string;
  9. myName(name: string) {
  10. console.log(name);
  11. this.name = name ;
  12. }
  13. ngOnInit() {
  14. }
  15. }
子组件 => 父组件 @output()

output这种常见的通信,本质是给子组件传入一个function,在子组件里执行完某些方法后,再执行传入的这个回调function,将值传给父组件

</>复制代码

  1. parent.component.ts
  2. @Component({
  3. selector: "app-child-to-parent",
  4. templateUrl: "./parent.component.html",
  5. styleUrls: ["./parent.component.css"]
  6. })
  7. export class ChildToParentComponent implements OnInit {
  8. childName: string;
  9. childNameForInject: string;
  10. constructor( ) { }
  11. ngOnInit() {
  12. }
  13. showChildName(name: string) {
  14. this.childName = name;
  15. }
  16. }

parent.component.html

</>复制代码

  1. output方式 childText:{{childName}}


</>复制代码

  1. child.component.ts
  2. export class OutputChildComponent implements OnInit {
  3. // 传入的回调事件
  4. @Output() public childNameEventEmitter: EventEmitter = new EventEmitter();
  5. constructor() { }
  6. ngOnInit() {
  7. }
  8. showMyName(value) {
  9. //这里就执行,父组件传入的函数
  10. this.childNameEventEmitter.emit(value);
  11. }
  12. }
注入父组件

这个原理的原因是父,子组件本质生命周期是一样的

</>复制代码

  1. export class OutputChildComponent implements OnInit {
  2. // 注入父组件
  3. constructor(private childToParentComponent: ChildToParentComponent) { }
  4. ngOnInit() {
  5. }
  6. showMyName(value) {
  7. this.childToParentComponent.childNameForInject = value;
  8. }
  9. }
sibling组件 => sibling组件 service Rxjs 通过service通信

angular中service是单例的,所以三种通信类型都可以通过service,很多前端对单例理解的不是很清楚,本质就是
,你在某个module中注入service,所有这个modul的component都可以拿到这个service的属性,方法,是共享的,所以常在app.moudule.ts注入日志service,http拦截service,在子module注入的service,只能这个子module能共享,在component注入的service,就只能子的component的能拿到service,下面以注入到app.module.ts,的service来演示

</>复制代码

  1. user.service.ts
  2. @Injectable()
  3. export class UserService {
  4. age: number;
  5. userName: string;
  6. constructor() { }
  7. }
  8. app.module.ts
  9. @NgModule({
  10. declarations: [
  11. AppComponent,
  12. SiblingAComponent,
  13. SiblingBComponent
  14. ],
  15. imports: [
  16. BrowserModule
  17. ],
  18. providers: [UserService],
  19. bootstrap: [AppComponent]
  20. })
  21. export class AppModule { }
  22. SiblingBComponent.ts
  23. @Component({
  24. selector: "app-sibling-b",
  25. templateUrl: "./sibling-b.component.html",
  26. styleUrls: ["./sibling-b.component.css"]
  27. })
  28. export class SiblingBComponent implements OnInit {
  29. constructor(private userService: UserService) {
  30. this.userService.userName = "王二";
  31. }
  32. ngOnInit() {
  33. }
  34. }
  35. SiblingAComponent.ts
  36. @Component({
  37. selector: "app-sibling-a",
  38. templateUrl: "./sibling-a.component.html",
  39. styleUrls: ["./sibling-a.component.css"]
  40. })
  41. export class SiblingAComponent implements OnInit {
  42. userName: string;
  43. constructor(private userService: UserService) {
  44. }
  45. ngOnInit() {
  46. this.userName = this.userService.userName;
  47. }
  48. }
通过Rx.js通信

这个是最牛逼的,基于订阅发布的这种流文件处理,一旦订阅,发布的源头发生改变,订阅者就能拿到这个变化;这样说不是很好理解,简单解释就是,b.js,c.js,d.js订阅了a.js里某个值变化,b.js,c.js,d.js立马获取到这个变化的,但是a.js并没有主动调用b.js,c.js,d.js这些里面的方法,举个简单的例子,每个页面在处理ajax请求的时候,都有一弹出的提示信息,一般我会在
组件的template中中放一个提示框的组件,这样很繁琐每个组件都要来一次,如果基于Rx.js,就可以在app.component.ts中放这个提示组件,然后app.component.ts订阅公共的service,就比较省事了,代码如下
首先搞一个alset.service.ts

</>复制代码

  1. import {Injectable} from "@angular/core";
  2. import {Subject} from "rxjs/Subject";
  3. @Injectable()
  4. export class AlertService {
  5. private messageSu = new Subject(); //
  6. messageObserve = this.messageSu.asObservable();
  7. private setMessage(message: string) {
  8. this.messageSu.next(message);
  9. }
  10. public success(message: string, callback?: Function) {
  11. this.setMessage(message);
  12. callback();
  13. }
  14. }

sibling-a.component.ts

</>复制代码

  1. @Component({
  2. selector: "app-sibling-a",
  3. templateUrl: "./sibling-a.component.html",
  4. styleUrls: ["./sibling-a.component.css"]
  5. })
  6. export class SiblingAComponent implements OnInit {
  7. userName: string;
  8. constructor(private userService: UserService, private alertService: AlertService) {
  9. }
  10. ngOnInit() {
  11. this.userName = this.userService.userName;
  12. // 改变alertService的信息源
  13. this.alertService.success("初始化成功");
  14. }
  15. }

app.component.ts

</>复制代码

  1. @Component({
  2. selector: "app-root",
  3. templateUrl: "./app.component.html",
  4. styleUrls: ["./app.component.css"]
  5. })
  6. export class AppComponent {
  7. title = "app";
  8. message: string;
  9. constructor(private alertService: AlertService) {
  10. //订阅alertServcie的message服务
  11. this.alertService.messageObserve.subscribe((res: any) => {
  12. this.message = res;
  13. });
  14. }
  15. }

这样订阅者就能动态的跟着发布源变化

总结: 以上就是常用的的通信方式,各种场景可以采取不同的方法

我的博客

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/52624.html

相关文章

  • Angular】Angula6中的组件通信

    摘要:组件通信本文主要介绍中的组件通信一父子组件通信父组件向子组件传递信息方法一在父组件上设置子组件的属性父组件绑定信息可设置子组件标题子组件接收消息方法二父组件调用子组件的方法父组件触发消息子组件接收消息来自子组件的打印子组件向父组件传 Angula6_组件通信 本文主要介绍 Angular6 中的组件通信 showImg(https://segmentfault.com/img/remo...

    voyagelab 评论0 收藏0
  • angular 组件通信

    摘要:单页面应用组件通信有以下几种,这篇文章主要讲通信父组件子组件子组件父组件组件组件父组件子组件子组件父组件本质上还是注入父组件不推荐使用局部变量的的的上面图表总结了能用到通信方案期中最后种是通用的的组件之间都可以使用这种其中是最最牛逼的用法甩 单页面应用组件通信有以下几种,这篇文章主要讲 Angular 通信 showImg(https://segmentfault.com/img/re...

    张金宝 评论0 收藏0
  • angular 组件通信

    摘要:单页面应用组件通信有以下几种,这篇文章主要讲通信父组件子组件子组件父组件组件组件父组件子组件子组件父组件本质上还是注入父组件不推荐使用局部变量的的的上面图表总结了能用到通信方案期中最后种是通用的的组件之间都可以使用这种其中是最最牛逼的用法甩 单页面应用组件通信有以下几种,这篇文章主要讲 Angular 通信 showImg(https://segmentfault.com/img/re...

    Zhuxy 评论0 收藏0
  • 前端知识点总结——Angular

    摘要:前端知识点总结一概述基于命令行的开发方式编译工作集成了打包工具。。。。在浏览器中接管展现应用的内容,并根据我们提供的操作指令响应用户的交互。在开发时,八大组成部分模块组件模板自带的标签指令绑定相关的的语法元数据告诉如何处理一个类。 前端知识点总结——Angular 一、Angular概述 基于命令行的开发方式? ①hot reload ②编译工作 ③集成了webpack打包工具 。。。...

    BaronZhang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<