微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

angular 组件通信的几种实现方式

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

  • 父组件 => 子组件
  • 子组件 => 父组件
  • 组件A = > 组件B

父组件 => 子组件 子组件 => 父组件 sibling => sibling

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

父组件 => 子组件

@input,最常用的一种方式

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

{{textContent}}

',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

rush:js;"> import { Component,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() 一般用在调用子组件非私有的方法

rush:js;"> import {Component,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); } }
rush:js;"> 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这个变量来表示子组件,就能调用子组件的方法了.

rush:xhtml;">

child 组件如下

rush:js;"> @Component({ selector: 'app-view-child-child',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

rush:js;"> @Component({ selector: 'app-child-to-parent',styleUrls: ['./parent.component.css'] }) export class ChildToParentComponent implements OnInit {

childName: string;
childNameForInject: string;
constructor( ) { }
ngOnInit() {
}
showChildName(name: string) {
this.childName = name;
}
}

parent.component.html

rush:xhtml;">
output方式 childText:{{childName}}


child.component.ts export class OutputChildComponent implements OnInit { // 传入的回调事件 @Output() public childNameEventEmitter: EventEmitter = new EventEmitter(); constructor() { } ngOnInit() { } showMyName(value) { //这里就执行,父组件传入的函数 this.childNameEventEmitter.emit(value); } }

注入父组件

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

rush:js;"> 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

rush:js;"> @Injectable() export class UserService { age: number; userName: string; constructor() { } }

app.module.ts

rush:js;"> @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

rush:js;"> @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里某个值变化,d.js立马获取到这个变化的,但是a.js并没有主动调用b.js,d.js这些里面的方法,举个简单的例子,每个页面在处理ajax请求的时候,都有一弹出的提示信息,一般我会在 组件的template中中放一个提示框的组件,这样很繁琐每个组件都要来一次,如果基于Rx.js,就可以在app.component.ts中放这个提示组件,然后app.component.ts订阅公共的service,就比较省事了,代码如下

首先搞一个alset.service.ts

rush:js;"> import {Injectable} from "@angular/core"; import {Subject} from "rxjs/Subject"; @Injectable() export class AlertService { private messageSu = new Subject(); // 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

rush:js;"> @Component({ selector: 'app-sibling-a',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

{ this.message = res; }); } }

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

总结: 以上就是常用的的通信方式,各种场景可以采取不同的方法。希望对大家的学习有所帮助,也希望大家多多支持编程之家。

原文地址:https://www.jb51.cc/js/31531.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐