Angular 2:更改 DOM 根 AppComponent 之外的元素
Angular 2: change DOM elements outside the root AppComponent
我有一个 observable -- loading$
-- 当我想在 UI 和 false 何时删除该覆盖层。可见性由 CSS class.
控制
当 Observable 发出 true 时,我想将 CSS class 添加到 <body>
,并在 [=] 上删除它44=]假.
html
<body class="">
<my-app>Angular app goes here</my-app>
</body>
如您所见,<body>
在我的 Angular 2
应用程序之外,因此我无法使用 属性 绑定来更改 class。这就是我目前所做的:
AppComponent.ts
loading$.subscribe(loading =>{
if(loading) document.querySelector('body').classList.add('loading');
else document.querySelector('body').classList.remove('loading');
});
这很好用。当 loading$
observable 发出 true/false 时,loading
class 是 added/removed。问题是我想在 Web Worker 中 运行 我的应用程序,这意味着无法访问 DOM。另外,Angular 建议不要直接操作 DOM。
如何使用 Angular
API 来更改 <body>
?
Angular 2
、typescript 2
、rxjs 5 beta 12
PS: looks promising, but the key link is dead. I've also seen a couple of suggestions that worked with Beta releases but are now obsolete (example)
尝试这样做:
<my-app>
<div class="your-class-for-loading"></div>
</my-app>
当my-app
准备就绪后,div将自动删除。
@ktretyak 的解决方案对我有用。基本上,我没有使用 <body>
,而是将 loading
class 放在 <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 样式,以及启用 loading
启动的事实,在 Javascript 加载和 Angular
引导程序时显示叠加层。
一旦加载 Angular
,<my-app>
中的所有内容将被替换为 AppComponent
模板。正如我在 OP 下方的评论中所解释的那样,我需要持续访问此加载叠加层,因为我在加载新路由期间显示它(当用户从一个路由组件导航到另一个路由组件时)。所以我不得不在模板
中包含相同的叠加层 div
app.component.html
<div id="overlay" [class.loading]="showLoading"></div>
<router-outlet></router-outlet>
现在,当我的 loading$
observable 触发时,我更改 class 属性 showLoading
并且 Angular 负责更新叠加层,因为它是现在是 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);
}
如果您希望在引导应用程序的过程中通过 DOM 替换实现不间断的动画,请使用以下方法。
将叠加层放在 my-app
元素之后。
<my-app></my-app>
<div id="overlay"></div>
在主成分class.ready
中添加@HostBinding
app.component.ts
:
@HostBinding('class.ready') ready: boolean = false;
在初始调用加载数据时更改 属性(当您的屏幕未完全呈现时,启动画面仍然可见)。
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;
}
}
我有一个 observable -- loading$
-- 当我想在 UI 和 false 何时删除该覆盖层。可见性由 CSS class.
当 Observable 发出 true 时,我想将 CSS class 添加到 <body>
,并在 [=] 上删除它44=]假.
html
<body class="">
<my-app>Angular app goes here</my-app>
</body>
如您所见,<body>
在我的 Angular 2
应用程序之外,因此我无法使用 属性 绑定来更改 class。这就是我目前所做的:
AppComponent.ts
loading$.subscribe(loading =>{
if(loading) document.querySelector('body').classList.add('loading');
else document.querySelector('body').classList.remove('loading');
});
这很好用。当 loading$
observable 发出 true/false 时,loading
class 是 added/removed。问题是我想在 Web Worker 中 运行 我的应用程序,这意味着无法访问 DOM。另外,Angular 建议不要直接操作 DOM。
如何使用 Angular
API 来更改 <body>
?
Angular 2
、typescript 2
、rxjs 5 beta 12
PS:
尝试这样做:
<my-app>
<div class="your-class-for-loading"></div>
</my-app>
当my-app
准备就绪后,div将自动删除。
@ktretyak 的解决方案对我有用。基本上,我没有使用 <body>
,而是将 loading
class 放在 <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 样式,以及启用 loading
启动的事实,在 Javascript 加载和 Angular
引导程序时显示叠加层。
一旦加载 Angular
,<my-app>
中的所有内容将被替换为 AppComponent
模板。正如我在 OP 下方的评论中所解释的那样,我需要持续访问此加载叠加层,因为我在加载新路由期间显示它(当用户从一个路由组件导航到另一个路由组件时)。所以我不得不在模板
app.component.html
<div id="overlay" [class.loading]="showLoading"></div>
<router-outlet></router-outlet>
现在,当我的 loading$
observable 触发时,我更改 class 属性 showLoading
并且 Angular 负责更新叠加层,因为它是现在是 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);
}
如果您希望在引导应用程序的过程中通过 DOM 替换实现不间断的动画,请使用以下方法。
将叠加层放在 my-app
元素之后。
<my-app></my-app>
<div id="overlay"></div>
在主成分class.ready
中添加@HostBinding
app.component.ts
:
@HostBinding('class.ready') ready: boolean = false;
在初始调用加载数据时更改 属性(当您的屏幕未完全呈现时,启动画面仍然可见)。
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;
}
}