当前位置: 首页 > Web前端 > HTML5

Angular组件通信

时间:2023-04-05 01:17:59 HTML5

单页应用程序组件通信有以下几种类型。本文主要讲Angular通信父组件=>子组件子组件=>父组件A组件=>组件B父组件=>子组件子组件=>父组件sibling=>sibling@input@outputsetters(本质上是@input)注入父组件ngOnChanges()(不推荐)局部变量@ViewChild()serviceserviceserviceRxjsObservalbeRxjsObservalbeRxjsObservalbelocalStorage,sessionStoragelocalStorage,sessionStoragelocalStorage,sessionStorage上图总结了可以使用的通信方案,最后三种是通用的,可以在两者之间使用angular组件,其中Rxjs是最强大的用法,redux,promise,这些也是基于函数状态管理的。,说说父组件=>子组件@input,最常用的方法@Component({selector:'app-parent',template:'

childText:
',styleUrls:['./parent.component.css']})exportclassParentComponentimplementsOnInit{varString:string;constructor(){}ngOnInit(){this.varString='从父组件传递';}}import{Component,OnInit,Input}from'@angular/core';@Component({selector:'app-child',template:'

{{textContent}}

',styleUrls:['./child.component.css']})exportclassChildComponentimplementsOnInit{@Input()publictextContent:string;constructor(){}ngOnInit(){}}settersetter是拦截@input属性,因为我们在组件通信的时候,经常需要对输入的属性进行处理,就需要一个setter。Setter和getter经常一起使用。将上面的child.component.tschild.component.tsimport{Component,OnInit,Input}from'@angular/core';@Component({selector:'app-child',template:'

{{textContent}}

',styleUrls:['./child.component.css']})导出类ChildComponent实现OnInit{_textContent:string;@Input()settextContent(text:string){this._textContent=!text:"Nothingwasgiventome"?文本;};获取textContent(){返回this._textContent;}constructor(){}ngOnInit(){}}onChange这是由角度生命周期钩子检测到的。私有方法import{Component,OnInit,ViewChild}from'@angular/core';从"../view-child-child/view-child-child.import{ViewChildChildComponent}导入。component";@Component({selector:'app-parent',templateUrl:'./parent.component.html',styleUrls:['./parent.component.css']})exportclassParentComponentimplementsOnInit{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({选择器:'app-view-child-child',templateUrl:'./view-child-child.component.html',styleUrls:['./view-child-child.component.css']})exportclassViewChildChildComponentimplementsOnInit{constructor(){}name:string;myName(name:string){控制台。日志(名称);this.name=名称;}ngOnInit(){}}局部变量局部变量类似于viewChild,只能在html模板中使用,修改parent.component.html,使用变量#viewChild表示子组件,然后子组件的方法即可局部变量值
子组件如下@Component({selector:'app-view-child-child',templateUrl:'./view-child-child.component.html',styleUrls:['./view-child-child.component.css']})exportclassViewChildChildComponentimplementsOnInit{构造函数(){}名称:字符串;myName(name:string){console.log(name);this.name=名称;}ngOnInit(){}}子组件=>父组件@output()output这种普通通信本质上是为子组件传入一个函数,在子组件中执行完某些方法后,执行传入的回调函数,并将值传递给父组件parent.component.ts@Component({selector:'app-child-to-parent',templateUrl:'./parent.component.html',styleUrls:['./parent.component.css']})exportclassChildToParentComponentimplementsOnInit{childName:string;childNameForInject:字符串;constructor(){}ngOnInit(){}showChildName(name:string){this.childName=name;}}parent.component.html

输出方法childText:{{childName}}


child.component.tsexportclassOutputChildComponentimplementsOnInit{//传入的回调事件@Output()publicchildNameEventEmitter:EventEmitter=newEventEmitter();constructor(){}ngOnInit(){}showMyName(value){//这里执行,父组件传入的函数this.childNameEventEmitter.emit(value);}}之所以采用注入父组件的原则,是因为父子组件的本质生命周期是相同的ngOnInit(){}showMyName(value){this.childToParentComponent.childNameForInject=value;}}siblingcomponent=>siblingcomponentserviceRxjs通过service进行通信Angular中的service是单例的,所以三种通信都可以通过service,很多前端对单例的理解不是很清楚。其实质就是当你在某个模块中注入一个服务时,这个模块的所有组件都可以获得这个服务的属性和方法。它们是共享的,所以经常在app.moudule.ts中注入日志服务,http拦截服务,子模块中注入的服务,只能被本子模块共享,组件中注入的服务只能获取子组件的service,下面注入到app.module.ts,service来演示user.service.ts@Injectable()exportclassUserService{age:number;用户名:字符串;constructor(){}}app.module.ts@NgModule({声明:[AppComponent,SiblingAComponent,SiblingBComponent],imports:[BrowserModule],providers:[UserService],bootstrap:[AppComponent]})exportclassAppModule{}SiblingBComponent.ts@Component({selector:'app-sibling-b',templateUrl:'./sibling-b.component.html',styleUrls:['./sibling-b.component.css']})导出类SiblingBComponent实现OnInit{constructor(privateuserService:UserService){this.userService.userName="王二";}ngOnInit(){}}SiblingAComponent.ts@Component({selector:'app-sibling-a',templateUrl:'./sibling-a.component.html',styleUrls:['./sibling-a.component.css']})exportclassSiblingAComponentimplementsOnInit{userName:string;constructor(privateuserService: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请求时,都会弹出提示信息。一般我都会在组件的模板里放一个提示框组件,很麻烦。如果是基于Rx.js的,可以把这个提示组件放在app.component.ts中,然后app.component.ts订阅公共服务就比较容易了。代码如下:首先创建一个alset.service.tsimport{Injectable}from"@angular/core";import{Subject}from"rxjs/Subject";@Injectable()exportclassAlertService{privatemessageSu=newSubject<字符串>();//信息eObserve=this.messageSu.asObservable();privatesetMessage(message:string){this.messageSu.next(message);}publicsuccess(message:string,callback?:Function){this.setMessage(message);打回来();}}sibling-a.component.ts@Component({选择器:'app-sibling-a',templateUrl:'./sibling-a.component.html',styleUrls:['./sibling-a.component.css']})exportclassSiblingAComponentimplementsOnInit{userName:string;构造函数(私有userService:UserService,私有警报服务: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']})exportclassAppComponent{标题='应用程序';消息:字符串;constructor(privatealertService:AlertService){//订阅alertServcie的消息服务this.alertService.messageObserve.subscribe((res:any)=>{this.message=res;});}}以便订阅者可以动态地跟踪我的博客发布源方式的变化