diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 76be12e7..9d69c371 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,9 +1,8 @@ import {Component, ViewEncapsulation} from '@angular/core'; -import {RouteConfig, Router} from '@angular/router-deprecated'; -import {Subscription} from 'rxjs/Subscription'; +import {RouteConfig} from '@angular/router-deprecated'; import {Pages} from './pages'; -import {ThemeGlobal} from "./theme"; +import {AppState} from "./app.state"; // TODO: is it really the best place to globally require that dependency? require("!style!css!sass!./theme/sass/_ionicons.scss"); @@ -36,16 +35,10 @@ export class App { isMenuCollapsed:boolean = false; - private _themeGlobalSubscription:Subscription; + constructor(private _state:AppState) { - constructor(private _themeGlobal:ThemeGlobal) { - this._themeGlobalSubscription = this._themeGlobal.getDataStream().subscribe((data) => { - this.isMenuCollapsed = data['menu.isCollapsed'] != null ? data['menu.isCollapsed'] : this.isMenuCollapsed; + this._state.subscribe('menu.isCollapsed', (isCollapsed) => { + this.isMenuCollapsed = isCollapsed; }); } - - ngOnDestroy() { - // prevent memory leak when component destroyed - this._themeGlobalSubscription.unsubscribe(); - } } diff --git a/src/app/app.state.ts b/src/app/app.state.ts new file mode 100644 index 00000000..b48c5c2e --- /dev/null +++ b/src/app/app.state.ts @@ -0,0 +1,43 @@ +import {Injectable} from '@angular/core' +import {Subject} from 'rxjs/Subject'; + +@Injectable() +export class AppState { + + private _data = new Subject(); + private _dataStream$ = this._data.asObservable(); + + private _subscriptions:Map> = new Map>(); + + constructor() { + this._dataStream$.subscribe((data) => this._onEvent(data)); + } + + notifyDataChanged(event, value) { + + let current = this._data[event]; + if (current != value) { + this._data[event] = value; + + this._data.next({ + event: event, + data: this._data[event] + }); + } + } + + subscribe(event:string, callback:Function) { + var subscribers = this._subscriptions.get(event) || []; + subscribers.push(callback); + + this._subscriptions.set(event, subscribers); + } + + _onEvent(data:any) { + var subscribers = this._subscriptions.get(data['event']) || []; + + subscribers.forEach((callback) => { + callback.call(null, data['data']); + }); + } +} diff --git a/src/app/index.ts b/src/app/index.ts index b37a9e1b..b344e030 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -1,8 +1,8 @@ // App -import {ThemeGlobal} from "./theme/theme.global"; +import {AppState} from "./app.state"; export * from './app.component'; // Application wide providers export const APP_PROVIDERS = [ - ThemeGlobal + AppState ]; diff --git a/src/app/theme/components/contentTop/contentTop.component.ts b/src/app/theme/components/contentTop/contentTop.component.ts index cce22b48..2ce50f48 100644 --- a/src/app/theme/components/contentTop/contentTop.component.ts +++ b/src/app/theme/components/contentTop/contentTop.component.ts @@ -1,7 +1,6 @@ import {Component} from '@angular/core'; -import {Subscription} from "rxjs/Subscription"; -import {ThemeGlobal} from "../../../theme"; +import {AppState} from "../../../app.state"; @Component({ selector: 'content-top', @@ -10,16 +9,10 @@ import {ThemeGlobal} from "../../../theme"; }) export class ContentTop { activePageTitle = ''; - private _themeGlobalSubscription:Subscription; - constructor(private _themeGlobal:ThemeGlobal) { - this._themeGlobalSubscription = this._themeGlobal.getDataStream().subscribe((data) => { - this.activePageTitle = data['menu.activeLink'] != null ? data['menu.activeLink'].title : this.activePageTitle; + constructor(private _state:AppState) { + this._state.subscribe('menu.activeLink', (activeLink) => { + this.activePageTitle = activeLink.title; }); } - - ngOnDestroy() { - // prevent memory leak when component destroyed - this._themeGlobalSubscription.unsubscribe(); - } } diff --git a/src/app/theme/components/pageTop/pageTop.component.ts b/src/app/theme/components/pageTop/pageTop.component.ts index c7856ea2..a71e2345 100644 --- a/src/app/theme/components/pageTop/pageTop.component.ts +++ b/src/app/theme/components/pageTop/pageTop.component.ts @@ -1,6 +1,6 @@ import {Component, ViewEncapsulation} from '@angular/core'; -import {ThemeGlobal} from '../../../theme'; +import {AppState} from '../../../app.state'; import {ProfilePicturePipe} from '../../pipes'; import {MsgCenter} from '../../components/msgCenter'; import {ScrollPosition} from '../../directives'; @@ -18,12 +18,12 @@ export class PageTop { isMenuCollapsed:boolean = false; - constructor(private _themeGlobal:ThemeGlobal) { + constructor(private _state:AppState) { } toggleMenu() { this.isMenuCollapsed = !this.isMenuCollapsed; - this._themeGlobal.setData('menu.isCollapsed', this.isMenuCollapsed); + this._state.notifyDataChanged('menu.isCollapsed', this.isMenuCollapsed); } scrolledChanged(isScrolled) { diff --git a/src/app/theme/components/sidebar/sidebar.component.ts b/src/app/theme/components/sidebar/sidebar.component.ts index 715b91d1..c6f287d5 100644 --- a/src/app/theme/components/sidebar/sidebar.component.ts +++ b/src/app/theme/components/sidebar/sidebar.component.ts @@ -1,7 +1,8 @@ import {Component, ElementRef, HostListener, ViewEncapsulation} from '@angular/core'; import {Router} from '@angular/router-deprecated'; -import {ThemeGlobal, layoutSizes} from '../../../theme'; +import {AppState} from '../../../app.state'; +import {layoutSizes} from '../../../theme'; import {SidebarService} from './sidebar.service'; // TODO: separate menu and sidebar @@ -33,7 +34,7 @@ export class Sidebar { constructor(private _elementRef:ElementRef, private _router:Router, private _sidebarService:SidebarService, - private _themeGlobal:ThemeGlobal) { + private _state:AppState) { } @@ -70,7 +71,7 @@ export class Sidebar { menuCollapseStateChange(isCollapsed) { this.isMenuCollapsed = isCollapsed; - this._themeGlobal.setData('menu.isCollapsed', this.isMenuCollapsed); + this._state.notifyDataChanged('menu.isCollapsed', this.isMenuCollapsed); } hoverItem($event) { @@ -123,6 +124,6 @@ export class Sidebar { }); // notifies all subscribers - this._themeGlobal.setData('menu.activeLink', currentMenu); + this._state.notifyDataChanged('menu.activeLink', currentMenu); } } diff --git a/src/app/theme/index.ts b/src/app/theme/index.ts index 17e2c853..6174b2e2 100644 --- a/src/app/theme/index.ts +++ b/src/app/theme/index.ts @@ -1,2 +1 @@ export * from './theme.constants' -export * from './theme.global' diff --git a/src/app/theme/theme.global.ts b/src/app/theme/theme.global.ts deleted file mode 100644 index 75587f1e..00000000 --- a/src/app/theme/theme.global.ts +++ /dev/null @@ -1,24 +0,0 @@ -import {Injectable} from '@angular/core' -import {Subject} from 'rxjs/Subject'; - -@Injectable() -export class ThemeGlobal { - private _data = new Subject(); - - dataStream$ = this._data.asObservable(); - - constructor() { - } - - setData(key, value) { - let current = this._data[key]; - if (current != value) { - this._data[key] = value; - this._data.next(this._data); - } - } - - getDataStream() { - return this.dataStream$; - } -}