2016-10-02 91 views
2

我有一個觀察的 - loading$ - 輸出真正當我想顯示在UI加載覆蓋,並當它的時間,以去除覆蓋。可見性由一個CSS類控制。角2:根外變化的DOM元素AppComponent

當可觀察發射真正,我想的CSS類添加到<body>,並刪除它

HTML

<body class=""> 
    <my-app>Angular app goes here</my-app> 
</body> 

正如你所看到的,<body>是我Angular 2應用程序之外,所以我不能使用屬性綁定更改類。這是我目前做的:

AppComponent.ts

loading$.subscribe(loading =>{ 
    if(loading) document.querySelector('body').classList.add('loading'); 
    else document.querySelector('body').classList.remove('loading'); 
}); 

這種運作良好。當loading$觀測值發射時,loading類被添加/刪除true/false。問題是我想在web worker中運行我的應用程序,這意味着無法訪問DOM。另外,Angular建議不要直接操縱DOM。

如何使用Angular API更改<body>

Angular 2typescript 2rxjs 5 beta 12

PS:This question看起來很有希望,但關鍵的環節是死的。我也看到了幾個與Beta發行工作的建議,但現在已經過時(example

+0

角允許您更改[頁面標題](https://angular.io/docs/ts/latest/cookbook/set-document -title.html),當我們談論有關Angular的外部元素的訪問時。爲什麼從外部操縱DOM對你來說很重要?爲什麼不把它放在'my-app'中? – ktretyak

+0

@ktretyak當'body'有'loading'類時,顯示一個加載覆蓋圖。 'index.html'默認將類設置爲ON。我希望網頁顯示這個加載覆蓋圖,直到它準備好用戶輸入爲止(直到加載了Angular根組件)。所以一旦組件加載,我使用'Angular'去除CSS類。同樣,當用戶離開組件時,我在'CanDeactivate'鉤子上啓用'loading',並在加載下一個路由時(在OnInit鉤子中)禁用它。 – BeetleJuice

+0

您可以使根組件非常輕量級(如''),並且在加載時不必等待。 – ktretyak

回答

1

嘗試做這樣的:

<my-app> 
    <div class="your-class-for-loading"></div> 
</my-app> 

my-app準備就緒,DIV將被自動刪除。

+0

謝謝。你的靈感來源於我的解決方案(我將它寫爲答案) – BeetleJuice

1

@ktretyak的解決方案爲我工作。基本上,而是採用<body>我把取loading類中<my-app>

的index.html

<body> 
    <my-app> 
     <div id="overlay" class="loading"></div> 
    </my-app> 
</body> 

CSS

#overlay { 
    position:fixed; 
    top:0; 
    left:0; 
    bottom:0; 
    right:0; 
    display:none; 
} 
#overlay.loading { 
    display:block 
} 

由於CSS樣式的DIV,和啓用了loading這一事實,則會在Javascript加載時顯示疊加層,並顯示Angular bootstraps。

一旦加載了Angular<my-app>中的所有內容都將替換爲AppComponent模板。正如我在OP下面的評論中所解釋的那樣,我需要持續訪問這個加載覆蓋,因爲我在加載新路由時顯示它(當用戶從​​一個路由組件導航到另一個時)。所以我不得不在模板中包括同一覆蓋DIV

app.component.html

<div id="overlay" [class.loading]="showLoading"></div> 
<router-outlet></router-outlet> 

現在,當我loading$觀察到的火災,我改變了一個類屬性showLoading和角負責更新因爲它覆蓋現在的AppComponent

部分app.component.ts

// set to true to show loading overlay. False to hide 
showLoading:boolean = true; 

ngOnInit(){ 
    // show/hide overlay depending on value emitted 
    loading$.subscribe(loading => this.showLoading = loading); 
} 
2

如果您想在引導應用程序的過程中通過DOM替換獲得不間斷的動畫,請使用以下方法。

將覆蓋圖放在my-app元素之後。當數據被加載初始呼叫(閃仍是可見的,當屏幕不能完全呈現)

@HostBinding('class.ready') ready: boolean = false; 

更改屬性:

<my-app></my-app> 
<div id="overlay"></div> 

的主要成分app.component.ts添加@HostBindingclass.ready

constructor(private contextService: ContextService) { 
    someService.initCall().then(r => this.ready = true); 
} 

使用CSS來隱藏裝載機:

my-app.ready + .overlay { 
    animation: hideOverlay 1s forwards; 
} 

@keyframes hideOverlay { 
    0% { 
     opacity: 1; 
    } 

    100% { 
     opacity: 0; 
     visibility: hidden; 
    } 
} 
+0

沒有測試過,但它確實很聰明! – BeetleJuice