Angular2 - Defining/Injecting 单例
Angular2 - Defining/Injecting Singleton
我定义了一个警报指令,如下所示:
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(导航栏、页脚、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');
}
}
这里的问题是我正在 newing
创建一个 AlertDirective
的新实例,因此我的 addAlert
方法正在添加到我的新实例的数组中,而不是现有实例这是在我的 app
组件中定义的。
如何将指令创建为单例并将单个实例注入每个视图,然后我可以在该单例上调用任何方法并影响每个注入的实例?
创建共享服务(仅在 bootstrap()
中注册)并使用它在组件和您的 AlertDirective
之间进行通信,例如 中的 showb
该服务还可以包含 EventEmitter
以便所有参与者都可以订阅传递的消息。
@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]);
我定义了一个警报指令,如下所示:
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(导航栏、页脚、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');
}
}
这里的问题是我正在 newing
创建一个 AlertDirective
的新实例,因此我的 addAlert
方法正在添加到我的新实例的数组中,而不是现有实例这是在我的 app
组件中定义的。
如何将指令创建为单例并将单个实例注入每个视图,然后我可以在该单例上调用任何方法并影响每个注入的实例?
创建共享服务(仅在 bootstrap()
中注册)并使用它在组件和您的 AlertDirective
之间进行通信,例如 EventEmitter
以便所有参与者都可以订阅传递的消息。
@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]);