前言
本文主要阐述关于在angular项目中,loading的常见的使用方式,以及如何全局挂载loading,实现一行代码控制loading开,一行代码控制loading关闭。
正文
首先在angular中增加loading,主要就是组件级和全局挂载,下面分别介绍
一、组件module级的引入loading
常见的angular的这种loading框,基本都是通过xxx.module.ts
中引入,这里我举例我们项目中使用的devexpress为例子,可以引入在imports中。
其中devpress的官网如下:https://js.devexpress.com/
主要是通过在各自的业务组件的module中引入,然后在html可以使用该标签,通过变量控制,下面是代码展示:
在业务的html中,直接写入这个标签即可
他的显示和隐藏主要通过isLoadPanelVisible变量的true和false去控制即可。如下
比较的简单,属于很常见的引用第三方组件库的方式。
缺点
如果你的module特别多,业务单据需要在每一个module中去引入,费时费力,且都是重复的代码
所以这时想到了全局挂loading。
大概想法分为以下几种:
- 想通过ng可以挂载全局组件,类似于vue的全局组件没在业务里直接引入该组件的html,通过变量控制,后查阅发现angular暂不支持,且引入还是很麻烦(遂放弃)
- 第二种全局loading用服务,放到一个module里导出,比如创建个sharedModule , 然后把模块放到exports: [CommonModule, …],用的时候, 就在各自的模块里imports:[sharedModule],但我们这业务module太多了 每个都得引一次,很麻烦(遂放弃)
- 第三种全局loading用服务,通过服务依赖注入到主app.component.ts中,只注入后挂载到了window上(最初想挂载到this),主要用到了rxjs的BehaviorSubject改变其变量,下文会详细介绍
全局挂载loading
关于angular的全局挂载loading,下面开始详细介绍:
- 最初我是想将loading,直接挂载到this上的,实现未果,在全局强行给this增加该服务,但业务上找不到,查了下原因,如下:
在 Angular 中,可以在组件类中使用 this 关键字来定义变量和方法,并且这些变量和方法将会成为组件的成员。
但是,在 Angular 中,一般不建议直接在 this 上挂载变量或方法,而是应该在组件类中显式声明它们作为组件的属性和方法。这种方式更符合 TypeScript 的类型检查和编译时检查,也更易于维护和调试。
如果你想要在 Angular 中定义共享状态或服务,应该考虑使用服务提供商(Service Provider)来实现。这种方式能够在整个应用程序中共享数据和逻辑。
所以放弃了this挂载,改用window挂载。
下面是使用服务的方式实现全局 loading 的代码示例:
第一步 创建服务LoadingService.ts
文件
首先新建一个LoadingService.ts
文件,代码如下:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class LoadingService {
private isLoading$ = new BehaviorSubject<boolean>(false);
private message$ = new BehaviorSubject<string>('正在加载中...');
constructor() {}
show(): void {
this.isLoading$.next(true);
}
hide(): void {
this.isLoading$.next(false);
}
setMessage(message: string): void {
this.message$.next(message);
}
get isLoading(): BehaviorSubject<boolean> {
return this.isLoading$;
}
get message(): BehaviorSubject<string> {
return this.message$;
}
}
第二部,在app.component.html
增加以下代码,用于loading的展示。
<div *ngIf="loadingService.isLoading | async" class="loading-overlay">
<div class="spinner"></div>
<div *ngIf="loadingService.message | async" class="loading-message">{{loadingService.message.getValue()}}</div>
</div>
第三部,在app.component.scss
设置loading的样式
!注意!这里的background,url我注释掉了,需要各自换成自己项目中的loading图片
.loading-overlay {
position: fixed;
z-index: 9999;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.spinner {
width: 150px;
height: 150px;
border-top: 4px solid #fff;
border-bottom: 4px solid #fff;
border-left: 4px solid rgba(255, 255, 255, 0.2);
border-right: 4px solid rgba(255, 255, 255, 0.2);
animation: spin 1s linear infinite;
// background:url("src/assets/img/logo.1.gif") no-repeat center center;
background-size: cover;
}
.loading-message {
color: #fff;
font-size: 14px;
margin-top: 10px;
display: block;
}
第四部,在app.component.ts
在主文件的ts里面,挂载刚刚写的LoadingService服务,代码如下。
import { Component } from '@angular/core';
import { LoadingService } from './loading.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
//依赖注入
constructor(public loadingService: LoadingService) {
//挂载到window上
window['nx_loading']=this.loadingService
}
}
至此,你的全局loading就挂载好了,下面在业务组件里使用
业务组件的使用非常简单,只有两行代码
- 开始loading:window[‘nx_loading’].show();
- 关闭loading:window[‘nx_loading’].hide();
伪代码demo如下:
他的展示效果如下(动图):
最后
关于angular的文章,可以查看我的主页。也可以访问我的博客如下
- angular框架简介基础与使用(全文2w8字)前端框架angular
- angular框架表格自定义导出
- 我的博客笔记
over bye~~~