angular组件通信


声明:本文转载自https://my.oschina.net/hucheng9110/blog/1538874,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

angular组件通信是很长常见的功能,现在总结下,常见通信主要用一下三种

  1. 父组件 => 子组件
  2. 子组件 => 父组件
  3. 组件A = > 组件B Screenshot.png-19.9kB

| 父组件 => 子组件 | 子组件 => 父组件 | 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,最常用的一种方式

@Component({   selector: 'app-parent', template: '<div>childText:<app-child  [textContent] = "varString"></app-child></div>',   styleUrls: ['./parent.component.css'] }) export class ParentComponent implements OnInit {   varString: string;   constructor() { }   ngOnInit() {     this.varString = '从父组件传过来的' ;   } } 
import { Component, OnInit, Input } from '@angular/core'; @Component({   selector: 'app-child',   template: '<h1>{{textContent}}</h1>',   styleUrls: ['./child.component.css'] }) export class ChildComponent implements OnInit {   @Input() public textContent: string ;   constructor() { }   ngOnInit() {   } } 

setter

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

import { Component, OnInit, Input } from '@angular/core'; @Component({   selector: 'app-child',   template: '<h1>{{textContent}}</h1>',   styleUrls: ['./child.component.css'] }) export class ChildComponent implements OnInit { _textContent:string;   @Input()    set textContent(text: string){    this._textContent = !text: "啥都没有给我" ? text ;   } ;   get textContent(){   return this._textContent;   }   constructor() { }   ngOnInit() {   } } 

onChange

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

@ViewChild()

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

           import {Component, OnInit, ViewChild} from '@angular/core';        import {ViewChildChildComponent} from "../view-child-child/view-child-child.component";     @Component({       selector: 'app-parent',       templateUrl: './parent.component.html',       styleUrls: ['./parent.component.css']     })     export class ParentComponent implements OnInit {       varString: string;       @ViewChild(ViewChildChildComponent)       viewChildChildComponent: ViewChildChildComponent;       constructor() { }       ngOnInit() {         this.varString = '从父组件传过来的' ;       }       clickEvent(clickEvent: any) {         console.log(clickEvent);         this.viewChildChildComponent.myName(clickEvent.value);       }     } 
      import { Component, OnInit } from '@angular/core';     @Component({       selector: 'app-view-child-child',       templateUrl: './view-child-child.component.html',       styleUrls: ['./view-child-child.component.css']     })     export class ViewChildChildComponent implements OnInit {       constructor() { }       name: string;       myName(name: string) {           console.log(name);           this.name = name ;       }       ngOnInit() {       }     } 

局部变量

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

<div class="panel-body">     <input class="form-control" type="text" #viewChildInputName >     <button class=" btn btn-primary" (click)="viewChild.myName(viewChildInputName.value)">局部变量传值</button>     <app-view-child-child #viewChild></app-view-child-child>             </div> 

child 组件如下

@Component({   selector: 'app-view-child-child',   templateUrl: './view-child-child.component.html',   styleUrls: ['./view-child-child.component.css'] }) export class ViewChildChildComponent implements OnInit {    constructor() { }   name: string;   myName(name: string) {       console.log(name);       this.name = name ;   }   ngOnInit() {   }  } 

子组件 => 父组件

@output()

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

parent.component.ts @Component({   selector: 'app-child-to-parent',   templateUrl: './parent.component.html',   styleUrls: ['./parent.component.css'] }) export class ChildToParentComponent implements OnInit {    childName: string;   childNameForInject: string;   constructor( ) { }   ngOnInit() {   }   showChildName(name: string) {     this.childName = name;   } } 

parent.component.html

<div class="panel-body">   <p>output方式 childText:{{childName}}</p>   <br>   <app-output-child (childNameEventEmitter)="showChildName($event)"></app-output-child> </div> 
  child.component.ts   export class OutputChildComponent implements OnInit {   // 传入的回调事件   @Output() public childNameEventEmitter: EventEmitter<any> = new EventEmitter();   constructor() { }   ngOnInit() {   }   showMyName(value) {     //这里就执行,父组件传入的函数     this.childNameEventEmitter.emit(value);   } } 

注入父组件

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

export class OutputChildComponent implements OnInit {   // 注入父组件   constructor(private childToParentComponent: ChildToParentComponent) { }   ngOnInit() {   }   showMyName(value) {     this.childToParentComponent.childNameForInject = value;   } } 

##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来演示

user.service.ts @Injectable() export class UserService {   age: number;   userName: string;   constructor() { } } app.module.ts @NgModule({   declarations: [     AppComponent,     SiblingAComponent,     SiblingBComponent   ],   imports: [     BrowserModule   ],   providers: [UserService],   bootstrap: [AppComponent] }) export class AppModule { } SiblingBComponent.ts @Component({   selector: 'app-sibling-b',   templateUrl: './sibling-b.component.html',   styleUrls: ['./sibling-b.component.css'] }) export class SiblingBComponent implements OnInit {   constructor(private userService: UserService) {     this.userService.userName = "王二";   }   ngOnInit() {   } } SiblingAComponent.ts @Component({   selector: 'app-sibling-a',   templateUrl: './sibling-a.component.html',   styleUrls: ['./sibling-a.component.css'] }) export class SiblingAComponent implements OnInit {   userName: string;   constructor(private userService: UserService) {   }   ngOnInit() {     this.userName = this.userService.userName;   } } 

通过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

import {Injectable} from "@angular/core"; import {Subject} from "rxjs/Subject"; @Injectable() export class AlertService {   private messageSu = new Subject<string>();  //   messageObserve = this.messageSu.asObservable();   private  setMessage(message: string) {     this.messageSu.next(message);   }   public success(message: string, callback?: Function) {     this.setMessage(message);     callback();   } } 

sibling-a.component.ts

@Component({   selector: 'app-sibling-a',   templateUrl: './sibling-a.component.html',   styleUrls: ['./sibling-a.component.css'] }) export class SiblingAComponent implements OnInit {   userName: string;   constructor(private userService: UserService, private alertService: AlertService) {   }   ngOnInit() {     this.userName = this.userService.userName;     // 改变alertService的信息源     this.alertService.success("初始化成功");   } } 

app.component.ts

@Component({   selector: 'app-root',   templateUrl: './app.component.html',   styleUrls: ['./app.component.css'] }) export class AppComponent {   title = 'app';   message: string;   constructor(private alertService: AlertService) {     //订阅alertServcie的message服务      this.alertService.messageObserve.subscribe((res: any) => {       this.message = res;     });   } } 

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

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

demo:https://github.com/hucheng91/angular2Learn/tree/master/angualar-component-communication 我的博客:http://blog.vinlineskater.com/

本文发表于2017年09月18日 08:36
(c)注:本文转载自https://my.oschina.net/hucheng9110/blog/1538874,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2176 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1