首页专栏详情
打赏
ThingsBoard教程(九):前端架构分析
易百纳技术社区 不完整教程 2021-03-15 15:41:39

前言

各位读者好,截止目前,ThingsBoard系列文章已经做了七篇,分别是

上一篇文章我们讲解了如何简单地定制物联网平台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是用于授权使用的。


声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。

13921
10
98
打赏
共1人已赏
完整的教程https://fizzz.blog.csdn.net。该网站都是残缺
评论
0个
内容存在敏感词
相关专栏
打赏作者
易百纳技术社区
不完整教程
您的支持将鼓励我继续创作!
打赏金额:
¥1 易百纳技术社区
¥5 易百纳技术社区
¥10 易百纳技术社区
¥50 易百纳技术社区
¥100 易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区 微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
Loading...
易百纳技术社区
确定要删除此文章、专栏、评论吗?
确定
取消
易百纳技术社区
易百纳技术社区
在专栏模块发布专栏,可获得其他E友的打赏
易百纳技术社区
回答悬赏问答,被题主采纳后即可获得悬赏金
易百纳技术社区
在上传资料时,有价值的资料可设置为付费资源
易百纳技术社区
达到一定金额,收益即可提现~
收益也可用来充值ebc,下载资料、兑换礼品更容易
易百纳技术社区
活动规则
  • 1.周任务为周期性任务,每周周一00:00刷新,上周完成的任务不会累计到本周,本周需要从头开始任务,当前任务完成后才可以完成下一个任务
  • 2.发布的专栏与资料需要与平台的板块有相关性,禁止注水,专栏/资料任务以审核通过的篇数为准,专栏需为原创文章且首次在社区发布
  • 3.任务完成后,现金奖励直接打款到微信账户;EBC/收益将自动发放到个人账户,可前往“我的钱包”查看;其他奖励请联系客服兑换
易百纳技术社区
升级提醒
易百纳技术社区

恭喜您由入门

社区送出礼品一份

请填写您的收件地址,礼品将在3个工作日寄出

易百纳技术社区