您现在的位置是:首页 >技术杂谈 >angular框架-通过依赖注入方式挂载loading以实现任意地方一行代码调用全局loading网站首页技术杂谈

angular框架-通过依赖注入方式挂载loading以实现任意地方一行代码调用全局loading

百事可口 2024-09-24 12:01:03
简介angular框架-通过依赖注入方式挂载loading以实现任意地方一行代码调用全局loading

前言

本文主要阐述关于在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。

大概想法分为以下几种:

  1. 想通过ng可以挂载全局组件,类似于vue的全局组件没在业务里直接引入该组件的html,通过变量控制,后查阅发现angular暂不支持,且引入还是很麻烦(遂放弃)
  2. 第二种全局loading用服务,放到一个module里导出,比如创建个sharedModule , 然后把模块放到exports: [CommonModule, …],用的时候, 就在各自的模块里imports:[sharedModule],但我们这业务module太多了 每个都得引一次,很麻烦(遂放弃)
  3. 第三种全局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的文章,可以查看我的主页。也可以访问我的博客如下

over bye~~~

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。