2016-02-09 122 views
1

最近我開始玩Angular 2和TypeScript,我想知道如何在整個網頁上訪問Singleton Class範圍html元素

我在做的是一個UIManagerService,目前只有一個boolean來檢查是否正在訪問一個UI組件。

有了這個boolean我想一個類被我<html>元素toggeled:

.noselect { 
    -o-user-select: none; 
    -moz-user-select: none; 
    -webkit-user-select: none; 
    user-select: none; 
} 

而且存取權限是這樣的:

<html [class.noselect] = "UIManagerService.HoldingUI"> 
... 
</html> 

更多Components將在年底存取權限此Singleton class


我的做法

在其他語言,我會用單類管理類課程。這是方法,我也TOKE:

export class UIManagerService { 
    holdingUI:Boolean; 

    static instance : UIManagerService; 
    static isCreating: Boolean = false; 

    constructor() { 
     if(!UIManagerService.isCreating) { 
      throw new Error("You can't call new in singletong instance"); 
     } 
    } 

    static getInstance() { 
     if(UIManagerService.instance == null) { 
      UIManagerService.isCreating = true; 
      UIManagerService.instance = new UIManagerService(); 
      UIManagerService.isCreating = false; 
     } 

     return UIManagerService.instance; 
    } 

    setHoldingUI(value) { 
     this.holdingUI = value; 
    } 

    getHoldingUI() { 
     return this.holdingUI; 
    } 
} 

(道具twofuckingdevelopers

現在,一旦我嘗試存取權限它在Component這個偉大工程:

export class Slider { 

    constructor() { 

    } 

    mousedown(event) { 
     UIManagerService.getInstance().setHoldingUI(true); 
     console.log(UIManagerService.getInstance().getHoldingUI()); 
    } 
} 

在此先感謝,

Nkmol

回答

2

在angular2中,您沒有做任何特殊的事情來創建單身服務。默認情況下他們是單身人士。因此,請使用angular提供的服務概念。另外值得一提的是,你在示例Slider組件中沒有使用依賴注入 - 由於很多原因,這是不好的。這兩個問題在這裏被深入描述:dependency injection in angular2

要訪問服務公開屬性或方法從你的組件,你可以在組件創建一個簡單的包裝屬性/方法:

@Component(.....) 
export class Slider 
{ 
    private m_service: UIManagerService; 

    constructor(service: UIManagerService) 
    { 
     this.m_service = service; 
    } 

    public test() 
    { 
     this.m_service.test(); 
    } 
} 

和引導電話:

引導( 應用, [ UIManagerService ]);

+0

謝謝你的回答。但是,這並沒有將其範圍限定在包含''和''元素的整個文檔中。這就是爲什麼我必須使用Singleton。 – nkmol

+1

我不明白''和「單身人士」是如何相關的。你的問題包含了很多代碼,但它並沒有說(實際)問題是什麼。您不能在''標籤之外使用類似[[class.noselect]]的綁定,即使在'標籤本身也不能。從你的問題,它看起來像你正在尋找類似https://github.com/angular/angular/blob/3c8fa8c50d820e3317bc40292c73df03c8b23e86/modules/angular2/src/platform/browser/title.ts –

+0

@GünterZöchbauer我的關係是因爲我無法'引導'我的''元素,我認爲singelton是我唯一的選擇。但正如你所說,我可能無法用「角度」來確定它的範圍。 關於你給的鏈接:我可能也使用普通的javascript'document'來訪問''元素? (看我的回答) – nkmol

2

同意已經給出的答案。

另外一個。

如果您希望Angular仍然使用您的getInstance函數來創建您的服務(也許您希望稍後添加更多邏輯,而不僅僅是「新建」),您可以執行此操作。

在你ui.manager.service.ts

import {provide} from 'angular2/core'; 

export class UIManagerService { 
    holdingUI: boolean; 

    static instance : UIManagerService; 
    static isCreating: Boolean = false; 

    constructor() { 
     if(!UIManagerService.isCreating) { 
      throw new Error("You can't call new in singleton instance"); 
     } 
    } 

    static getInstance(): UIManagerService { 
     if(UIManagerService.instance == null) { 
      UIManagerService.isCreating = true; 
      UIManagerService.instance = new UIManagerService(); 
      UIManagerService.isCreating = false; 
     } 

     return UIManagerService.instance; 
    } 

    setHoldingUI(value): void { 
     this.holdingUI = value; 
    } 

    getHoldingUI(): boolean { 
     return this.holdingUI; 
    } 

    test(): void { 
     console.log("This is coming from UIManagerService"); 
    } 
} 

export let UIManagerServiceProvider = provide(UIManagerService, { 
    useFactory:() => { 
     return UIManagerService.getInstance(); 
    } 
}); 

出口其調用getInstanceUIManagerServiceProvider

在主應用程序(對我來說的app.component.ts):

import {Component} from 'angular2/core'; 
import {UIManagerService, UIManagerServiceProvider} from './ui.manager.service'; 

@Component({ 
    selector: 'my-app', 
    template: `<h1 (mousedown)="_uiManagerService.test()">Angular 2 App</h1>`, 
    providers: [UIManagerServiceProvider] 
}) 
export class AppComponent { 
    constructor(private _uiManagerService: UIManagerService) { 
    } 
} 

正如你可以在模板中看到你可以調用test功能。

(mousedown)="_uiManagerService.test()" 
+0

真的很酷。不知道這個!但是,我仍然無法訪問''元素,因爲從我讀過的內容來看,Angular 2沒有訪問''元素的外部,也沒有訪問'document'。 – nkmol

0

由於角2似乎並沒有能夠範圍<html>元素,我解決了這個問題只需通過使用普通的JavaScript:

Slider.ts

export class Slider { 

    constructor() { 

    } 

    mousedown() { 
     UIManagerService.getInstance().setHoldingUI(true); 
    } 

    mouseup() { 
     UIManagerService.getInstance().setHoldingUI(false); 
    } 
} 

無需因爲它不在範圍之內,所以我無法啓動一些東西。

UIManagerService.ts

export class UIManagerService { 
    holdingUI:Boolean; 
    htmlClass = 'noselect'; 

    static instance : UIManagerService; 
    static isCreating: Boolean = false; 

    constructor() { 
     if(!UIManagerService.isCreating) { 
      throw new Error("You can't call new in singletong instance"); 
     } 
    } 

    static getInstance() { 
     if(UIManagerService.instance == null) { 
      UIManagerService.isCreating = true; 
      UIManagerService.instance = new UIManagerService(); 
      UIManagerService.isCreating = false; 
     } 

     return UIManagerService.instance; 
    } 

    setHoldingUI(value) { 
     if(value) 
      this.addHTMLClass(); 
     else 
      this.removeHTMLClass(); 
     this.holdingUI = value; 
    } 

    getHoldingUI() { 
     return this.holdingUI; 
    } 

    // Toggle specific class 
    toggleHtmlClass() { 
     document.documetElement.classList.toggle(this.htmlClass); 
    } 
} 

這不是最乾淨的解決方案但它的工作。現在我保留這個答案,直到有更好的答案