Angular 2:修改AppComponent根组件之外的DOM元素



我有一个可观察对象——loading$——当我想在UI中显示加载覆盖时,输出true,当需要删除覆盖时,输出false。可见性是通过一个CSS类来控制的。

当Observable发出true时,我想给<body>添加CSS类,并在false上删除它。

<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$可观察对象发出true/false时,添加/删除loading类。问题是,我想在一个web工作者这意味着没有访问DOM运行我的应用程序。另外,Angular建议不要直接操作DOM。

如何使用Angular api来更改<body> ?

Angular 2, typescript 2, rxjs 5 beta 12

PS:这个问题看起来很有希望,但关键环节是死的。我也看到了一些在Beta版本中有效的建议,但现在已经过时了(例如)

如果你想在应用启动过程中通过DOM替换来获得不间断的动画,那么请使用以下方法:

my-app元素后添加叠加。

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

在主组件app.component.ts中添加@HostBindingclass.ready:

@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;
  }
}

@ktretyak的解决方案让我的工作。基本上,我没有使用<body>,而是将loading类的div放在<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$可观察对象着火时,我改变了一个类属性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);
}

试着这样做:

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

my-app准备好后,div会自动移除

最新更新