Angular2 - 定义/注入Singleton

时间:2016-02-03 00:42:03

标签: typescript angular angular2-directives

我定义了一个警告指令,如下所示:

import { Component } from 'angular2/core';
import { CORE_DIRECTIVES } from 'angular2/common';
import { Alert } from 'ng2-bootstrap/ng2-bootstrap';

@Component({
  selector: 'alert_directive',
  templateUrl: './shared/directives/alert/alert.html',
  directives: [Alert, CORE_DIRECTIVES]
})
export class AlertDirective {
  alerts:Array<Object> = [ ];

  closeAlert(i:number) {
    this.alerts.splice(i, 1);
  }

  addAlert(message: string, style: string) {
    this.alerts.push({msg: message, type: style, closable: true});
    console.log(this.alerts);
  }
}

然后我定义了我的app组件,其中包含了这个指令:

import {AlertDirective} from '../../shared/directives/alert/alert';
...
@Component({
  selector: 'app',
  templateUrl: './app/components/app.html',
  styleUrls: ['./app/components/app.css'],
  providers: [UserService, HTTP_PROVIDERS],
  encapsulation: ViewEncapsulation.None,
  directives: [ROUTER_DIRECTIVES, AlertDirective]
})
...

这一切都有效,并且该指令显示在与我的app.html文件相关的DOM中。

app.html文件包含一些全局html(navbar,footer,alert_directive)。我希望alert_directive成为一个单例,我可以更改alerts数组以显示来自任何视图的警报消息,而无需将指令添加到每个视图。

所以,在另一个sign in组件中:

import {Component, ViewEncapsulation} from 'angular2/core';
import {AlertDirective} from '../../shared/directives/alert/alert';
@Component({
  selector: 'sign_in',
  templateUrl: './sign_in/components/sign_in.html',
  styleUrls: ['./sign_in/components/sign_in.css'],
  encapsulation: ViewEncapsulation.Emulated
})
export class SignInCmp {
  alertDirective: AlertDirective;
  constructor(alertDirective: AlertDirective) {
    this.alertDirective = alertDirective;
  }

  showAlert() {
    this.alertDirective.addAlert('test', 'warning');
  }
}

这里的问题是我newingAlertDirective的实例,因此我的addAlert方法正在添加到我的新实例的数组中,而不是现有的实例。在我的app组件中定义。

如何将指令创建为单例并将单个实例注入到每个视图中,然后我可以调用该单例上的任何方法并影响每个注入的实例?

1 个答案:

答案 0 :(得分:3)

创建共享服务(仅在bootstrap()中注册),并使用它在组件和AlertDirective中的EventEmitter类似showb进行通信 该服务还可以包含@Injectable() export class AlertService { command: EventEmitter = new EventEmitter(); } @Component({ selector: 'alert_directive', templateUrl: './shared/directives/alert/alert.html', directives: [Alert, CORE_DIRECTIVES] }) export class AlertDirective { constructor(private alertService: AlertService) { alertService.commands.subscribe((command) => { doSomething();} } alerts:Array<Object> = [ ]; closeAlert(i:number) { this.alerts.splice(i, 1); } addAlert(message: string, style: string) { this.alerts.push({msg: message, type: style, closable: true}); console.log(this.alerts); } } @Component({ selector: 'sign_in', templateUrl: './sign_in/components/sign_in.html', styleUrls: ['./sign_in/components/sign_in.css'], encapsulation: ViewEncapsulation.Emulated }) export class SignInCmp { alertDirective: AlertDirective; constructor(alertService: AlertService) { this.alertService = alertService; } showAlert() { this.sharedService.command.next({text: 'test', title: 'warning'}); } } bootstrap(AppComponent, [/* other providers */, AlertService]); ,以便所有参与者都可以订阅传递的消息。

div{
                width: auto;
                float: left;
            }
            a{
                color: red;
                text-decoration: none;
                padding: 5px 20px;
                float: left;
                position: relative;
            }
            a:hover{
                color:#FFF;
            }
            a:after{
                content: '';
                background: red;
                position: absolute;
                top: 50%;
                right: 5%;
                bottom: 50%;
                left: 5%;
                border-radius: 3px;
                transition: all .1s;
                z-index: -1;
            }
            a:hover:after{
                top: 0;
                right: 0;
                bottom: 0;
                left: 0;
            }