AngularJs 2 - 创建了多个服务实例

Phi*_*lon 27 angular2-services angular

我创建了AngularJS 2服务,并在2个不同的组件中使用它:App-Component&Sub-Component.每个输出属性'log'(一个字符串)我的服务.

StateService类:

@Injectable ()
class StateService {

    public log : string;
    static count : number = 0;

    constructor () {
        this.log = '';
        StateService.count++;
        this.writeToLog ('CREATED '+StateService.count+' at ' + new Date().toString());
    }

    public writeToLog (text : string) : void {
        this.log += text + '\n';
    }
}  
Run Code Online (Sandbox Code Playgroud)

零件 :

@Component ({
    selector : 'Sub-Component',
    template : `<hr>
            This is the Sub-Component !
            <BR>
            StateService Log : 
            <pre>{{ _stateService.log }}</pre>
            <button (click)="WriteToLog ()">Write to log</button>
            `,
    providers : [StateService]
})

export class SubComponent {
    constructor (private _stateService : StateService) {
    }

    public WriteToLog () : void {
        this._stateService.writeToLog ('From Sub-Component - This is '+new Date().toString());
    }
}
Run Code Online (Sandbox Code Playgroud)

这里是代码的实例

我除了创建一次服务之外,当每个组件调用WriteToLog方法时,每个组件的输出都相同,但事实并非如此.

输出示例:

App-Component可以输出:

实例1 - 创建于2016年1月21日星期四11:43:51

来自App-Component - 这是2016年1月21日星期四11:43:54

来自App-Component - 这是2016年1月21日星期四11:43:55

并且子组件可以输出:

实例2 - 创建于2016年1月21日星期四11:43:51

来自子组件 - 这是2016年1月21日星期四11:43:57

从子组件 - 这是2016年1月21日星期四11:43:58

所以似乎创建了2个服务实例(实例1 +实例2)

我只想要一个实例;)当我在日志中追加字符串时,它必须出现在两个组件中.

谢谢您的帮助

Gün*_*uer 32

更新角度> = 2.0.0-RC.6

不要将服务添加到组件的提供者.而是将其添加到

@NgModule({ providers: [...], ...
Run Code Online (Sandbox Code Playgroud)

(由于延迟加载的模块引入了自己的范围,因此加载延迟的模块)

@Component ({
    selector : 'Sub-Component',
    template : `<hr>
            This is the Sub-Component !
            <BR>
            StateService Log : 
            <pre>{{ _stateService.log }}</pre>
            <button (click)="WriteToLog ()">Write to log</button>
            `,
    // providers : [StateService] <== remove
})
Run Code Online (Sandbox Code Playgroud)

角度<= 2.0.0-RC.5

如果将其添加到组件上,则会为每个组件实例获取新的服务实例.而是将其添加到

bootstrap(AppComponent, [StateService]);
Run Code Online (Sandbox Code Playgroud)

您可以通过将其添加到单个组件来进行更细粒度的控制,然后此组件和所有子项都会注入相同的实例,否则应用程序将使用由其创建的实例bootstrap().这是Angulars DI中的"等级".

另见
- http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html
- http://blog.thoughtram.io/angular/2015/09/17 /resolve-service-dependencies-in-angular-2.html

  • 好问题.我没有在文档中明确提到它,但有很多文档,我没有全部阅读.我是在开发AngularDart 1.0的过程中从讨论中学到的.DI为每个提供商维护一个实例.每个提供程序实例都指向一个服务实例.这就是为什么如果在为应用程序多次添加的组件上提供服务,则会获得多个实例.对于全局添加的提供者(AppComponent,NgModule),将只有一个实例. (2认同)
  • 如果你想要整个应用程序的单个实例,请将它放在`@NgModule(...)`中.如果你想为每个组件实例(以及它的子组件)提供单个实例,并且该组件外部的服务不可用,那么将它放在`@Component(...)中 (2认同)