2016-07-29 114 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中任何组件的父级应用程序。 –