2016-07-29 116 views
1

我已經完成了關於在組件之間共享服務的一些閱讀,以及使用應用程序組件的基本思想,我的理解是本質上創建服務的單例作爲提供程序。Angular2共享HTTP服務

我加載了一個具有嵌套組件的組件,嵌套組件都使用這個共享服務。將來會觸發頁面上的事件,現在我需要HTTP服務來更新和更新所有嵌套組件模板元素。我該如何「強制」更新?

此外,這是否意味着因爲我共享應用程序組件中的服務,HTTP服務將在頁面「root」組件加載時運行?

還是我不正確理解?我的意思是使用指令嗎?

+0

你不需要強制任何東西。當Angular2更改檢測檢測到更改時,它將更新HTML。 HTTP請求將在組件訂閱時進行。如果您從服務構造函數中進行訂閱,則會在第一次在某處注入該服務時(這是創建實例時)發出請求。 –

+0

葉我有點意識到,當服務更新任何訂閱組件會更新(指令是否正確?),但我想弄清事實,讓我們說我有一個儀表板頁面和組件需要更新多個嵌套組件當服務更新時,我在什麼時候實際調用服務更新?在嵌套組件加載後的儀表板組件中? – Wancieho

+0

您將使用接收服務的組件上的ngOnInit接口初始化初始狀態,並在ngOnInit生命週期掛接方法內執行初始化邏輯。之後對服務的任何更新都可以從任何組件隨時調用。請參閱https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html –

回答

1

更新:我沒有時間把這個週末放在一起,但是如果事情還不清楚,我做了a simplified example to show how service injection works in Angular 2

AppComponent將AppService列爲@Component裝飾器中的提供者,這意味着服務的單例在此組件級別注入。在ChildComponent中,該服務不需要被列爲提供者,因爲它將使用注入到AppComponent中的相同實例。它所需要做的就是導入AppService模塊,並在構造函數definiton中注入服務。

相反,IsolatedComponent使用AppService的單獨實例,所以它通過其@Component裝飾器中的providers數組注入一個新的單例實例。 IsolatedChildComponent將使用IsolatedComponent所使用的相同服務實例,因此對於ChildComponent而言,它所需要做的就是導入AppService模塊,並將該實例注入其構造函數定義中。

請注意,每當組件初始化時,每個組件都會更新共享綁定屬性,消息,並且子組件會自動捕獲這些更新。相同的邏輯可以應用於進行API調用的服務。

下面是服務和組件的代碼:

app.service.ts

import { Injectable } from '@angular/core'; 

@Injectable() 
export class AppService { 
    messages: string[] = []; 

    updateMessages(msg: string) { 
    this.messages.push(msg); 
    } 
} 

app.component.ts

import { Component, OnInit } from '@angular/core'; 
import { AppService } from './app.service'; 
import { ChildComponent } from './child.component'; 
import { IsolatedComponent } from './isolated.component'; 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <h1>AppComponent Tree</h1> 
    <p> 
    AppComponent and ChildComponent consume the same instance of AppService 
    </p> 
    <child-component></child-component> 
    <hr /> 
    <isolated-component></isolated-component> 
    `, 
    providers: [AppService], 
    directives: [ChildComponent, IsolatedComponent] 
}) 
export class AppComponent implements OnInit { 
    messages: string[]; 

    constructor(private appService: AppService) { 
    this.messages = appService.messages; 
    } 

    ngOnInit() { 
    this.addMessage(`AppComponent Initialized`); 
    } 

    private addMessage(msg: string) { 
    this.appService.updateMessages(msg); 
    } 
} 

child.component .ts

import { Component, OnInit } from '@angular/core'; 
import { AppService } from './app.service'; 

@Component({ 
    selector: 'child-component', 
    template: ` 
    <div *ngFor="let message of messages">{{message}}</div> 
    ` 
}) 
export class ChildComponent implements OnInit { 
    messages: string[]; 

    constructor(private appService: AppService) { 
    this.messages = appService.messages; 
    } 

    ngOnInit() { 
    this.addMessage(`ChildComponent Initialized`); 
    } 

    private addMessage(msg: string) { 
    this.appService.updateMessages(msg); 
    } 
} 

isolated.component.ts

import { Component, OnInit } from '@angular/core'; 
import { AppService } from './app.service'; 
import { IsolatedChildComponent } from './isolated-child.component'; 

@Component({ 
    selector: 'isolated-component', 
    template: ` 
    <h1>Isolated Component Tree</h1> 
    <p> 
    IsolatedComponent and IsolatedChildComponent consume an 
    instance of AppService separate from the AppComponent tree 
    </p> 
    <isolated-child></isolated-child> 
    `, 
    providers: [AppService], 
    directives: [IsolatedChildComponent] 
}) 
export class IsolatedComponent implements OnInit { 
    messages: string[]; 

    constructor(private appService: AppService) { 
    this.messages = appService.messages; 
    } 

    ngOnInit() { 
    this.addMessage(`IsolatedComponent initialized`); 
    } 

    private addMessage(msg: string) { 
    this.appService.updateMessages(msg); 
    } 
} 

孤立child.component.ts

import { Component, OnInit } from '@angular/core'; 
import { AppService } from './app.service'; 

@Component({ 
    selector: 'isolated-child', 
    template: ` 
    <div *ngFor="let message of messages">{{message}}</div> 
    ` 
}) 
export class IsolatedChildComponent implements OnInit { 
    messages: string[]; 

    constructor(private appService: AppService) { 
    this.messages = appService.messages; 
    } 

    ngOnInit() { 
    this.addMessage(`IsolatedChildComponent initialized`); 
    } 

    private addMessage(msg: string) { 
    this.appService.updateMessages(msg); 
    } 
} 

參見Hierarchical Injectors文檔。

+0

因此,如果您的頁面具有多個依賴於相同服務的組件,則可以加載所有組件以及「底部「頁面組件調用服務,以便每個組件然後更新?也許我的問題並不完全清楚? – Wancieho

+0

我得到你所得到的。你會做的是在第一個相關的父組件中注入服務作爲提供者,然後在任何後續的子組件中,在構造函數中注入服務。樹中的所有組件都會引用相同的服務實例,並且任何受服務更改影響的綁定都會自動反映到組件中。 –

+0

現在,如果組件不在同一個組件樹中,並且您希望它們都使用相同的服務進行編排,您仍然可以通過注入AppComponent來實現此目的,該組件應該是Angular中任何組件的父級應用程序。 –