ThingsBoard教程(九):前端架构分析
前言
各位读者好,截止目前,ThingsBoard系列文章已经做了七篇,分别是
- ThingsBoard教程(一):ThingBoard介绍及安装
- ThingsBoard教程(二):租户,租户配置,部件组模块的使用
- ThingsBoard教程(三):系统设置模块的使用
- ThingsBoard教程(四):规则链简介与操作
- ThingsBoard教程(五):客户,资产管理
- ThingsBoard教程(六):设备管理
- ThingsBoard教程(七):模拟设备遥测
- ThingsBoard教程(八):自定义UI
上一篇文章我们讲解了如何简单地定制物联网平台ThingsBoard的logo以及title,还有主题色,本篇文档我将带领大家继续深究一下ThingsBoard的前端源码,读这些源码,分享系统的机构,不仅能够帮助我们快速地自定义定制tb,也能够让我们从中获取灵感,学到很多设计上的技巧。
话不多说,让我们开始吧。
目录介绍
先来说一下项目的目录,这个是最为直观的。
一些常见的文件我们就不说了,像yarn.lock,tslint.json,LICENSE,package.json,tsconfig.json,几乎每个前端项目都会有。这里不多做解释。
-
e2e 测试目录
-
angular.json angular框架的工作目录配置文件 详细配置说明
-
src 所有源码所在地
src 下又有以下几个目录
- app 核心代码-存放页面,路由,业务逻辑,数据流转的代码
- assets 静态资源-图片,国际化配置,
- environments 环境变量-开发环境,生成环境 环境变量
- scss scss-提取出的公共样式,scss,方法,变量
- typings ts类型-定义的用于辅助编写ts代码的装饰器,类型,
- theme.scss 主题配置-主色,配色,辅助色,字体大小
- style.scss 样式重置-样式主入口,样式重置
- main.ts 程序入口
- thingsboard.ico 网站图标
- index.html 网站入口
- karna.conf.js 测试配置
架构技术栈
打开前端目录ui-ngx,找到package.json。我们就能看到里面有很多以@angular开头的依赖包,此外很多脚本指令都是 以ng开头,根据以上判断,Thingsboard是一个使用Angular框架搭建的web架构。使用的是"@angular/cli": "^10.1.5",
脚手架来搭建的。使用了TypeScript。有部分的React代码,主要集中公共组件部分。
ui组件使用的是material-ui
。
可以看到引入了一下几个包
"@angular/material": "^10.2.4",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/pickers": "^3.2.10",
"material-design-icons": "^3.0.1",
"ngx-daterangepicker-material": "^4.0.1",
使用jwt来进行授权认证管理。
数据流转
数据流转就是,一个项目中,数据是如何流转的,
- 数据通过那个几个方法渲染到页面上?
- 如何将页面的表单数据通过api接口发送给后端
- 数据如何存储的?全局数据,组件数据,
- 组件如何通信,如何传递数据?
- 。。。。
所有有关数据的流转,都是比较重要的,因为如果要去改造tb,必须要知道这部分的知识才能改的动。
我们来看一下,登录页面的数据流转。
打开login.component.ts
我们看到
loginFormGroup = this.fb.group({
username: '',
password: ''
});
这里对页面的表单数据进行了初始化,一个用户名,一个密码。你可以尝试给这两个属性赋值,看是否 会显示到页面上。
在方法login()
中我们看到
login(): void {
if (this.loginFormGroup.valid) {
this.authService.login(this.loginFormGroup.value).subscribe(
() => {},
(error: HttpErrorResponse) => {
if (error && error.error && error.error.errorCode) {
if (error.error.errorCode === Constants.serverErrorCode.credentialsExpired) {
this.router.navigateByUrl(`login/resetExpiredPassword?resetToken=${error.error.resetToken}`);
}
}
}
);
} else {
Object.keys(this.loginFormGroup.controls).forEach(field => {
const control = this.loginFormGroup.get(field);
control.markAsTouched({onlySelf: true});
});
}
}
首先是对表单进行了验证,使用valid。验证成功后,调用authService这个服务中的login方法,参数就是表单的数据,在subscribe 传入了二个函数,用于处理正确,和错误的结果。
这个数据我们就知道了,表单数据由页面传递到了authService中的login方法中。接着我们去这个服务中寻找具体的实现逻辑
这里便是login的逻辑代码
public login(loginRequest: LoginRequest): Observable<LoginResponse> {
return this.http.post<LoginResponse>('/api/auth/login', loginRequest, defaultHttpOptions()).pipe(
tap((loginResponse: LoginResponse) => {
this.setUserFromJwtToken(loginResponse.token, loginResponse.refreshToken, true);
}
));
}
我们看到底层是调用this.http.post
方法,接口地址是/api/auth/login
, 接口返回后又使用了setUserFromJwtToken
函数来处理。
要理解ng中的数据流转,要多看看rxjs。
路由
路由使用的是@angular/router
。所有的路由都分别在app内中的 *-routing.module.ts
中,随便找一个,
以下是login-routing.module.ts
中的代码,引入了@angular/core和@angular/router
NgModule 是ng中的包管理,用于模块的导出和引入。
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from './pages/login/login.component';
import { AuthGuard } from '@core/guards/auth.guard';
import { ResetPasswordRequestComponent } from '@modules/login/pages/login/reset-password-request.component';
import { ResetPasswordComponent } from '@modules/login/pages/login/reset-password.component';
import { CreatePasswordComponent } from '@modules/login/pages/login/create-password.component';
const routes: Routes = [
{
path: 'login',
component: LoginComponent,
data: {
title: 'login.login',
module: 'public'
},
canActivate: [AuthGuard]
},
{
path: 'login/resetPasswordRequest',
component: ResetPasswordRequestComponent,
data: {
title: 'login.request-password-reset',
module: 'public'
},
canActivate: [AuthGuard]
},
{
path: 'login/resetPassword',
component: ResetPasswordComponent,
data: {
title: 'login.reset-password',
module: 'public'
},
canActivate: [AuthGuard]
},
{
path: 'login/resetExpiredPassword',
component: ResetPasswordComponent,
data: {
title: 'login.reset-password',
module: 'public',
expiredPassword: true
},
canActivate: [AuthGuard]
},
{
path: 'login/createPassword',
component: CreatePasswordComponent,
data: {
title: 'login.create-password',
module: 'public'
},
canActivate: [AuthGuard]
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class LoginRoutingModule { }
具体的用法就是这样
{
path: 'login',
component: LoginComponent,
data: {
title: 'login.login',
module: 'public'
},
canActivate: [AuthGuard]
},
- path是router的路径,
- component指向路径到达的组件,
- data是进入该组件的额外信息,很像mate信息,
- AuthGuard是用于授权使用的。
- 分享
- 举报
-
小张 2024-04-19 22:00:15回复 举报帮助不大
-
浏览量:19013次2021-03-22 17:45:29
-
浏览量:11165次2021-08-12 18:08:27
-
浏览量:11098次2021-07-23 15:56:25
-
浏览量:11222次2021-07-13 16:37:15
-
浏览量:9386次2021-07-24 18:04:04
-
浏览量:10683次2021-07-20 15:29:50
-
浏览量:13978次2021-08-13 16:08:47
-
浏览量:11689次2021-07-07 12:13:40
-
浏览量:3031次2019-11-09 19:10:44
-
浏览量:21118次2021-02-02 19:39:27
-
浏览量:33919次2021-03-03 17:25:19
-
浏览量:15996次2021-02-07 11:52:24
-
浏览量:2613次2020-11-28 18:52:29
-
浏览量:33631次2021-02-02 16:24:27
-
浏览量:27036次2021-02-05 17:49:30
-
浏览量:4866次2021-04-12 15:49:26
-
浏览量:1461次2024-01-25 16:21:59
-
浏览量:490次2023-07-17 13:48:57
-
浏览量:1715次2020-06-08 15:18:15
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
这把我C
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明