【问题标题】:Angular2 - Defining/Injecting SingletonAngular2 - 定义/注入单例
【发布时间】:2016-05-12 00:41:46
【问题描述】:

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

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');
  }
}

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

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

【问题讨论】:

  • 我想更好的方法是使用服务,而不是使该组件单例

标签: typescript angular angular2-directives


【解决方案1】:

创建一个共享服务(仅在bootstrap() 中注册)并使用它在组件和您的AlertDirective 之间进行通信,例如How do i share data between components in Angular2? 中的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]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    • 2016-05-16
    • 1970-01-01
    相关资源
    最近更新 更多