Angular 2:更改根AppComponent之外的DOM元素

时间:2016-10-02 00:12:38

标签: dom angular typescript rxjs5

我有一个可观察的 - loading$ - 当我想在用户界面中显示加载叠加层时输出 true ,而当它想要显示加载叠加层时 false 39;是时候删除那个叠加层了。可见性由CSS类控制。

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

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 observable发出 true / false 时,会添加/删除loading$类。问题是我想在网络工作者中运行我的应用程序,这意味着无法访问DOM。另外,Angular建议不要直接操纵DOM。

如何使用Angular API更改<body>

Angular 2typescript 2rxjs 5 beta 12

PS:This question看起来很有希望,但关键环节已经死了。我还看到了一些与Beta版本配合使用但现已过时的建议(example

3 个答案:

答案 0 :(得分:2)

如果您希望在引导应用程序的过程中通过DOM替换不间断的动画,请使用以下方法。

将叠加层置于my-app元素之后。

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

@HostBinding添加到主要组件class.ready中的app.component.ts

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

使用初始调用加载数据时更改属性(当屏幕未完全呈现时,splash仍然可见。)

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

答案 1 :(得分:1)

尝试这样做:

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

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

答案 2 :(得分: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样式以及启用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触发时,我更改了一个类属性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);
}