繁体   English   中英

角度2:在根AppComponent外部更改DOM元素

[英]Angular 2: change DOM elements outside the root AppComponent

我有一个可观察到的loading$ -当我想在UI中显示一个加载叠加层时输出true ,而当需要删除该叠加层时输出false 可见性由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: 这个问题看起来很有希望,但是关键环节已经死了。 我还看到了一些与Beta版本兼容的建议,但现在已经过时了( 示例

如果您想在启动应用程序的中间通过DOM替换来提供不间断的动画,请使用以下方法。

将叠加层放在my-app元素之后。

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

添加@HostBindingclass.ready的主要成分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;
  }
}

尝试这样做:

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

my-app准备就绪时,div将被自动删除。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM