亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

angular 組件通信的幾種實現方式

2019-11-19 13:30:08
字體:
來源:轉載
供稿:網友

單頁面應用組件通信有以下幾種,這篇文章主要講 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,最常用的一種方式

@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;  }); }}

這樣訂閱者就能動態的跟著發布源變化

總結: 以上就是常用的的通信方式,各種場景可以采取不同的方法。希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
最近的2019中文字幕免费一页| 久久精品人人爽| 日本精品免费一区二区三区| 亚洲国产成人精品久久| 国产精品久久久久免费a∨大胸| 人体精品一二三区| www国产亚洲精品久久网站| 夜夜嗨av色一区二区不卡| 在线免费观看羞羞视频一区二区| 精品视频在线播放色网色视频| 91丨九色丨国产在线| 久热精品视频在线观看一区| 国产精品你懂得| 亚洲欧美日韩久久久久久| 欧美黑人视频一区| 成人精品网站在线观看| 成人在线视频福利| 伊人久久久久久久久久| 国产69精品99久久久久久宅男| 久久影院中文字幕| 这里只有精品丝袜| 国产小视频国产精品| 国产香蕉精品视频一区二区三区| 亚洲乱码一区av黑人高潮| 亚洲国产精品人久久电影| 欧美日本啪啪无遮挡网站| 欧美日韩在线看| 欧美性猛交xxxx久久久| 欧美野外wwwxxx| 欧美性生活大片免费观看网址| 日韩电影免费在线观看中文字幕| 亚洲第一视频网站| 欧美日韩在线视频首页| 亚洲美女精品成人在线视频| 黑人巨大精品欧美一区二区一视频| 欧美精品一区二区免费| 国产精品亚洲综合天堂夜夜| 日韩av有码在线| 亚洲毛茸茸少妇高潮呻吟| 国产精品 欧美在线| 色无极影院亚洲| 狠狠色狠狠色综合日日小说| 国产精品美女视频网站| 国产精品福利观看| 成人黄色av网站| 亚洲精品自拍视频| 亚洲中国色老太| 欧美极品少妇xxxxⅹ裸体艺术| 国产精品欧美一区二区三区奶水| 欧美激情免费观看| 国产精品免费网站| 国产一区二区av| 亚洲成人久久电影| 2024亚洲男人天堂| 欧美最猛性xxxxx亚洲精品| www.xxxx欧美| 亚洲欧美日韩国产中文专区| 亚洲国产婷婷香蕉久久久久久| 亚洲欧美日韩另类| 国产精品亚洲自拍| 欧美国产精品va在线观看| 亚洲欧美日韩精品久久| 97在线视频免费| 色噜噜狠狠色综合网图区| 亚洲成人在线视频播放| 久久久噜噜噜久久中文字免| 国产成人免费av| 欧美福利视频在线| 欧美日韩高清区| 最新亚洲国产精品| 久久久久久999| 国产一区私人高清影院| 日韩一区二区福利| 91国内揄拍国内精品对白| 国产91色在线| 国产视频在线观看一区二区| 国产一区二区黄| 国产+人+亚洲| 欧美有码在线视频| 久久精品国产v日韩v亚洲| 欧美久久精品午夜青青大伊人| 午夜精品久久久久久久久久久久久| 欧美激情xxxx| 欧美精品aaa| 欧洲成人在线视频| 色视频www在线播放国产成人| 性色av一区二区三区| 日韩在线中文字幕| 久久久精品欧美| 久久国产色av| 欧洲成人性视频| 伊人成人开心激情综合网| 在线播放日韩欧美| 九九热精品视频国产| 欧美日韩亚洲精品内裤| 日韩va亚洲va欧洲va国产| 成人字幕网zmw| 福利微拍一区二区| 91精品久久久久久久| 国产99久久精品一区二区 夜夜躁日日躁| 国产精品18久久久久久首页狼| 国产精品亚洲美女av网站| 亚洲人成电影网站色www| 韩日欧美一区二区| 午夜精品99久久免费| 久久视频在线直播| 久久人人爽国产| 日韩av网站导航| 77777少妇光屁股久久一区| 中文字幕日韩精品在线观看| 亚洲精品视频免费| 黑人精品xxx一区| 精品视频在线观看日韩| 91在线|亚洲| 91色琪琪电影亚洲精品久久| 成人疯狂猛交xxx| 欧美中文字幕视频| 欧美电影免费观看高清完整| 欧美性猛交xxx| 国产丝袜一区视频在线观看| 国产精品一区二区三区久久| 国产精品美乳在线观看| 欧美在线xxx| 日韩精品中文字幕有码专区| 精品国产一区久久久| 亚洲欧美在线x视频| 黑人与娇小精品av专区| 欧美美女15p| 成人免费在线视频网站| 欧美专区在线播放| 亚洲第一精品久久忘忧草社区| 亚洲国产高清自拍| 伊人久久五月天| 综合国产在线观看| 国产一区二区三区在线视频| 国产成人短视频| 久久精品视频中文字幕| 欧美亚洲第一区| 亚洲日本aⅴ片在线观看香蕉| 国产精品1区2区在线观看| 国产精品一区二区久久国产| 国产女人18毛片水18精品| 亚洲福利在线播放| 国产成人小视频在线观看| 国产视频精品在线| 国产999精品久久久影片官网| 国产成人精品亚洲精品| 伊人久久免费视频| 欧美与欧洲交xxxx免费观看| 国产精品69久久| 91久久久亚洲精品| 欧美激情一区二区三区久久久| 国产成+人+综合+亚洲欧美丁香花| 日韩网站免费观看| 美女999久久久精品视频| 国产日韩中文字幕| 欧美视频在线视频| 一个人www欧美| 亚洲福利视频专区| 欧美最猛性xxxx| 欧美亚洲午夜视频在线观看| 欧美日韩精品二区| 久久精品国产欧美激情| 97久久精品人人澡人人爽缅北|