1. 組件通信
成都創(chuàng)新互聯(lián)自2013年創(chuàng)立以來,是專業(yè)互聯(lián)網(wǎng)技術服務公司,擁有項目成都做網(wǎng)站、網(wǎng)站制作網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元七星做網(wǎng)站,已為上家服務,為七星各地企業(yè)和個人服務,聯(lián)系電話:18980820575
我們知道Angular2應用程序?qū)嶋H上是有很多父子組價組成的組件樹,因此,了解組件之間如何通信,特別是父子組件之間,對編寫Angular2應用程序具有十分重要的意義,通常來講,組件之間的交互方式主要有如下幾種:
本文會通過講解著幾種方式來對組件之間的通信做一個大致的介紹。
2. 輸入型綁定
輸入型綁定指的是利用模板語法中的屬性型綁定方式,將父組件的數(shù)據(jù)傳遞到子組件對應的對象中,子組件中的對象一般使用@Input裝飾器來修飾,作為數(shù)據(jù)的接受者,例如
@Component({ selector: 'child', template: 'I am fron {{input}}' }) export class ChildComponent implements OnInit { @Input() input; constructor() { } ngOnInit() { } } @Component({ selector: 'parent', template: '' }) export class ParentComponent implements OnInit { data: string; constructor() { } ngOnInit() { this.data = "parent"; } }
以上的例子我們可以看出,存在父子兩個組件,在父組件ParentComponent中的模板中引入了
輸入型綁定是從父組件傳遞數(shù)據(jù)到子組件最常見的方式。
3. setter監(jiān)聽
我們知道,Angular2是一個MVVM的框架,當數(shù)據(jù)發(fā)生變化時能夠同步顯示到模板視圖中,可以使用一個輸入屬性的 setter 函數(shù),以攔截父組件中值的變化,并采取行動。例如,我們改造上面的例子,子組件中使用set,get重寫對應的綁定input屬性,當輸入值方式變化時輸出一個控制臺信息。
@Component({ selector: 'child', template: 'I am fron {{data}}' }) export class ChildComponent implements OnInit { _input:string; @Input() public set input(v : string) { this._input = v; console.log(v); } public get input() : string { return this._input; } constructor() { } ngOnInit() { } }
4. ngOnChanges
除了上面說的setter函數(shù)可以響應輸入數(shù)據(jù)的變化外,Angular2還提供了一個生命周期函數(shù)ngOnChanges 可以監(jiān)聽數(shù)據(jù)的變化。使用 OnChanges 生命周期鉤子接口的 ngOnChanges 方法來監(jiān)測輸入屬性值的變化并做出回應。我們改造以上的子組件來響應對應的變化,在這個示例中,我們監(jiān)聽了輸入數(shù)據(jù)的變化,采取的對應動作僅僅是輸出對應的信息,當然你也可以做很多其他的事情。
@Component({ selector: 'child', template: 'I am fron {{data}}' }) export class ChildComponent implements OnInit, OnChanges { _input: string; @Input() public set input(v: string) { this._input = v; console.log(v); } public get input(): string { return this._input; } constructor() { } ngOnInit() { } ngOnChanges(changes: SimpleChanges) { console.log(changes); } }
5. 事件傳播
上面的集中方式都是父組件如何向子組件傳遞數(shù)據(jù)以及子組件如何監(jiān)聽數(shù)據(jù)的變化,事件傳播則是子組件如何向父組件通信的一種方式。子組件暴露一個 EventEmitter 屬性,當事件發(fā)生時,子組件利用該屬性 emits( 向上彈射 ) 事件。父組件綁定到這個事件屬性,并在事件發(fā)生時作出回應。子組件的 EventEmitter 屬性是一個 輸出屬性 ,通常帶有 @Output 裝飾器 。
@Component({ selector: 'child', template: ` I am fron {{data}}
` }) export class ChildComponent implements OnInit, OnChanges { _input: string; @Input() public set input(v: string) { this._input = v; console.log(v); } public get input(): string { return this._input; } @Output() output:EventEmitter= new EventEmitter (); click(){ this.output.emit("i am from child"); } constructor() { } ngOnInit() { } ngOnChanges(changes: SimpleChanges) { console.log(changes); } } @Component({ selector: 'parent', template: ' ' }) export class ParentComponent implements OnInit { data: string; constructor() { } ngOnInit() { this.data = "parent"; } output($event){ console.log($event); } }
在上面的例子中,我們在子組件ChildComponent添加了一個向外傳播的事件output:EventEmitter
使用事件傳播來進行子組件對父組件之間的通信是最常見的方式。
6. 本地變量
在模板語法中,我們知道存在著本地變量這種語法,可以使用本地變量來代表對應的組件。雖然父組件不能使用數(shù)據(jù)綁定來讀取子組件的屬性或調(diào)用子組件的方法。但可以在父組件模板里,新建一個本地變量來代表子組件,然后利用這個變量來讀取子組件的屬性和調(diào)用子組件的方法,不過這種使用方式只能在模板中使用,例如如下所示,改寫上面例子中的父組件模板,代碼如下。
我們在ParentComponent組件中使用本地變量#child獲取了child組件的實例,這樣就可以在模板中使用其屬性或者方法,例如child.input。
@Component({ selector: 'parent', template: '{{child.input}}' }) export class ParentComponent implements OnInit { data: string; constructor() { } ngOnInit() { this.data = "parent"; } output($event){ console.log($event); } }
7. ViewChild
本地變量的方式是在父組件的模板中獲取子組件的實例,有木有其他方式可以在組件的類中獲取子組件的實例呢?答案是肯定的,如果父組件的類需要讀取子組件的屬性值或調(diào)用子組件的方法,就不能使用本地變量方法。當父組件類 需要這種訪問時,可以把子組件作為ViewChild,注入到父組件里面。例如,我們改造上面的父組件的組件類,使用ViewChild來獲取子組件的實例,代碼如下:
@Component({ selector: 'parent', template: '{{child.input}}' }) export class ParentComponent implements OnInit { @ViewChild(ChildComponent) private childComponent: ChildComponent; data: string; constructor() { } ngOnInit() { this.data = "parent"; } output($event) { console.log($event); } }
在以上的代碼中,我們使用@ViewChild(ChildComponent)注解的形式獲取了對應子組件childComponent的實例,這樣在父組件類中就可以調(diào)用子組件對應的屬性及方法了。
相對于本地變量的方式而言,ViewChild的方式更加靈活,用途也比較廣泛。但是,需要注意的一點是,必須等待父組件的視圖顯示完成后才可以使用,因此,ngAfterViewInit 生命周期鉤子是非常重要的一步。
8. 服務方式
通過服務依賴注入的方式,我們可以了解到,服務在父子組件之間是可以共享的,因此,我們可以利用共享的服務的形式在父子組件之間進行通信。
如果我們將服務實例的作用域被限制在父組件和其子組件內(nèi),這個組件子樹之外的組件將無法訪問該服務或者與它們通訊。
一般來說,父子之間使用服務的方式來通行,是采用事件消息的形式來實現(xiàn)的。
例如,如下的代碼中,父子組件中共享了Service服務,并在各自的類中獲取了Service服務的實例,當分別點擊父子組件中的按鈕時,就能夠觸發(fā)Service服務中的對應的input$以及output$,因為服務是共享的,所以在父子組件中監(jiān)聽對應的服務信息,就能夠得到傳遞的消息。
@Injectable() export class Service { input$: EventEmitter= new EventEmitter (); output$: EventEmitter = new EventEmitter (); constructor() { } } @Component({ selector: 'child', template: ` ` }) export class ChildComponent { constructor(private _service: Service) { this._service.input$.subscribe(function (input: string) { console.log(input); }) } click() { this._service.output$.emit('i am from child'); } } @Component({ selector: 'parent', template: ' ', providers: [Service] }) export class ParentComponent { constructor(private _service: Service) { this._service.output$.subscribe(function (output: string) { console.log(output); }) } click() { this._service.input$.emit('i am from child'); } }
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。