2016-02-03 3 views
0

Я предупреждение директива определена, например, так:Angular2 - Определение/Инъекционное 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] 
}) 
... 

Это все работает, и директива отображается в DOM, связанном с моим файлом app.html.

Этот файл 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'); 
    } 
} 

Вопрос здесь я newing вверх новый экземпляр AlertDirective, и поэтому мой addAlert метод добавляет в массив моего нового экземпляра, не существующий экземпляр, который определен в моем компоненте app.

Как создать директиву в качестве одноэлементного объекта и вставить один экземпляр в каждый вид, где я могу затем вызвать любой метод на этом одиночном тоне и повлиять на каждый введенный экземпляр?

+0

Я думаю, что лучший способ - использовать сервис, а не делать этот компонент singleton – sdfacre

ответ

2

Создать общую службу (только зарегистрированный в bootstrap()) и использовать его для связи между компонентами и вашей AlertDirective как showb в How do i share data between components in Angular2? Служба может также содержать 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]);