国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > 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;  }); }}

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

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 上犹县| 泽普县| 始兴县| 新营市| 毕节市| 资中县| 华坪县| 沙洋县| 缙云县| 五原县| 德格县| 启东市| 眉山市| 卓尼县| 集安市| 富锦市| 翁牛特旗| 桐梓县| 循化| 历史| 平昌县| 岐山县| 津南区| 五寨县| 堆龙德庆县| 礼泉县| 察哈| 喀什市| 壤塘县| 徐汇区| 阿图什市| 宜良县| 沙雅县| 乐都县| 平湖市| 郸城县| 安达市| 楚雄市| 太和县| 昭平县| 大埔区|