• 技术文章 >web前端 >js教程

    Angular + NG-ZORRO快速开发一个后台系统

    青灯夜游青灯夜游2022-05-09 21:34:27转载1029
    本篇文章给大家分享一个Angular实战,了解一下angualr 结合 ng-zorro 如何快速开发一个后台系统,希望对大家有所帮助!

    连更的这几天的文章,我们已经了解了不少 angular 的知识点了,这次我们来个小成品。

    angualr 结合 ng-zorro 快速且规范的开发一个后台系统。【相关教程推荐:《angular教程》】

    系统功能包括下面的内容:

    所有的 service 使用模拟的数据。

    说干咱就干。

    结合 ng-zorro

    angular 比较流行的 ui 框架有:

    Ant Design 相信做前端开发的人儿都比较熟悉了。所以这里我们结合 NG-ZORRO 这个框架来做。如果熟悉 Vue 或者 React 版本的 Ant Design,相信你可以无缝链接啊~

    1.png

    我们重新使用 angular-cli 生成一个项目 ng-zorro

    添加 ng-zorro 是很简单的事情:进入 ng-zorro 根目录,执行 ng add ng-zorro-antd 即可。

    当然你也可以执行 npm install ng-zorro-antd 添加,不推荐。

    结合 ng-zorro 完成之后,我们运行项目起来 npm run start,你会在 http://localhost:4200 的页面看到下图内容。

    2.png

    Not Bad, Bro.

    配置路由

    我们改成 hash 路由,并添加用户路由,脚手架都帮我们完事了,我们只要做点小修改。

    思路:

    按照思路,我们得在 ng-zorro 引入:

    // app.module.ts
    
    import { ReactiveFormsModule } from '@angular/forms';
    import { NzTableModule } from 'ng-zorro-antd/table';
    import { NzModalModule } from 'ng-zorro-antd/modal';
    import { NzButtonModule } from 'ng-zorro-antd/button';
    import { NzFormModule } from 'ng-zorro-antd/form';
    import { NzInputModule } from 'ng-zorro-antd/input';
    
    
    // ...
    
    imports: [ // 是在 imports 中添加,而不是 declarations 中声明
      NzTableModule,
      NzModalModule,
      NzButtonModule,
      NzFormModule,
      ReactiveFormsModule,
      NzInputModule
    ],

    简单易理解原则,我们这里不使用 children 进行路由的嵌套:

    // app.routing.module.ts
    
    import { NgModule } from '@angular/core';
    import { Routes, RouterModule, PreloadAllModules } from '@angular/router';
    import { WelcomeComponent } from './pages/welcome/welcome.component';
    import { UserComponent } from './pages/user/user.component';
    import { UserInfoComponent } from './pages/user/user-info/user-info.component';
    
    // 相关的路由
    const routes: Routes = [
      { 
        path: '', 
        pathMatch: 'full', 
        redirectTo: '/welcome' 
      },
      {
        path: 'welcome',
        component: WelcomeComponent
      },
      {
        path: 'user',
        component: UserComponent
      },
      {
        path: 'user/add',
        component: UserInfoComponent
      },
      {
        path: 'user/edit/:uuid',
        component: UserInfoComponent
      }
    ];
    
    @NgModule({
      imports: [RouterModule.forRoot(
        routes,
        {
          useHash: true,// 使用 hash 模式
          preloadingStrategy: PreloadAllModules
        }
      )],
      exports: [RouterModule]
    })
    export class AppRoutingModule { }

    更改菜单

    使用脚手架生成的菜单与我们需要开发的功能不符合,我们来调整下。

    // app.component.html
    
    <nz-layout class="app-layout">
      <nz-sider class="menu-sidebar"
                nzCollapsible
                nzWidth="256px"
                nzBreakpoint="md"
                [(nzCollapsed)]="isCollapsed"
                [nzTrigger]="null">
        <div class="sidebar-logo">
          <!-- 默认点击 logo 跳转到首页 -->
          <a routerLink="/welcome">
            <img src="https://ng.ant.design/assets/img/logo.svg" alt="logo">
            <h1>Ng-Zorro</h1>
          </a>
        </div>
        <ul nz-menu nzTheme="dark" nzMode="inline" [nzInlineCollapsed]="isCollapsed">
          <li nz-submenu nzOpen nzTitle="用户管理" nzIcon="dashboard">
            <ul>
              <li nz-menu-item nzMatchRouter>
                <a routerLink="/user">用户列表</a>
              </li>
            </ul>
          </li>
        </ul>
      </nz-sider>
      <nz-layout>
        <nz-header>
          <div class="app-header">
            <span class="header-trigger" (click)="isCollapsed = !isCollapsed">
                <i class="trigger"
                   nz-icon
                   [nzType]="isCollapsed ? 'menu-unfold' : 'menu-fold'"
                ></i>
            </span>
          </div>
        </nz-header>
        <nz-content>
          <div class="inner-content">
            <router-outlet></router-outlet>
          </div>
        </nz-content>
      </nz-layout>
    </nz-layout>

    菜单展示,如果我们需要做权限管理的话,是需要后端配合进行传值的,然后我们再把相关的权限菜单渲染到页面

    替换成上面的代码后,得到的基本骨架如下:

    3.png

    完成用户列表

    接下来完成用户列表的骨架,因为使用了 UI 框架,我么写起来异常的方便:

    获取用户列表

    // user.component.html
    
    <nz-table #basicTable [nzData]="list">
      <thead>
        <tr>
          <th>Name</th>
          <th>Position</th>
          <th>Action</th>
        </tr>
      </thead>
      <tbody>
        <!-- 对获取到的数据进行遍历 -->
        <tr *ngFor="let data of basicTable.data">
          <td>{{data.name}}</td>
          <td>{{data.position}}</td>
          <td>
            <a style="color: #f00;">Delete</a>
          </td>
        </tr>
      </tbody>
    </nz-table>

    我们模拟了些数据在 assets 文件夹中 user.json:

    {
      "users": [
        {
          "uuid": 1,
          "name": "Jimmy",
          "position": "Frontend"
        },
        {
          "uuid": 2,
          "name": "Jim",
          "position": "Backend"
        }
      ],
      "environment": "development"
    }

    编写好服务之后,我们调用获取用户的数据:

    // user.component.ts
    
    import { Component, OnInit } from '@angular/core';
    import { UserService } from 'src/app/services/user.service';
    
    @Component({
      selector: 'app-user',
      templateUrl: './user.component.html',
      styleUrls: ['./user.component.scss']
    })
    export class UserComponent implements OnInit {
    
      public list: any = []
    
      constructor(
        private readonly userService: UserService
      ) { }
    
      ngOnInit(): void {
        if(localStorage.getItem('users')) {
          let obj = localStorage.getItem('users') || '{}'
          this.list =  JSON.parse(obj)
        } else {
          this.getList()
        }
      }
    
      // 获取用户列表
      getList() {
        this.userService.getUserList().subscribe({
          next: (data: any) => {
            localStorage.setItem('users', JSON.stringify(data.users))
            this.list = data.users
          },
          error: (error: any) => {
            console.log(error)
          }
        })
      }
    
    }

    因为没有引入后端服务,这里我们采用 localstorage 的方式记录状态。

    上面完成后,我们得到列表信息如下:

    4.png

    新增用户和编辑用户

    我们简单建立个表单,里面含有的字段就两个,分别是 nameposition。这两个功能是公用一个表单的~

    我们在 html 中添加:

    // user-info.component.html
    
    <form nz-form [formGroup]="validateForm" class="login-form" (ngSubmit)="submitForm()">
      <nz-form-item>
        <nz-form-control nzErrorTip="请输入用户名!">
          <input type="text" nz-input formControlName="username" placeholder="请输入用户名" style="width: 160px;" />
        </nz-form-control>
      </nz-form-item>
      <nz-form-item>
        <nz-form-control nzErrorTip="请输入职位!">
          <input type="text" nz-input formControlName="position" placeholder="请输入职位" style="width: 160px;"/>
        </nz-form-control>
      </nz-form-item>
      <button nz-button class="login-form-button login-form-margin" [nzType]="'primary'">确认</button>
    </form>

    页面长这样子:

    5.png

    然后就是逻辑的判断,进行添加或者是修改。如果是连接带上 uuid 的标识,就表示是编辑,show you the codes

    // user-info.component.ts
    
    import { Component, OnInit } from '@angular/core';
    import { FormBuilder, FormGroup, Validators } from '@angular/forms';
    import { ActivatedRoute, ParamMap } from '@angular/router';
    
    @Component({
      selector: 'app-user-info',
      templateUrl: './user-info.component.html',
      styleUrls: ['./user-info.component.scss']
    })
    export class UserInfoComponent implements OnInit {
    
      public isAdd: boolean = true;
      public userInfo: any = []
      public uuid: number = 0;
    
      validateForm!: FormGroup;
    
      constructor(
        private fb: FormBuilder,
        private route: ActivatedRoute,
      ) { }
    
      ngOnInit(): void {
        this.userInfo = JSON.parse(localStorage.getItem('users') || '[]')
        this.route.paramMap.subscribe((params: ParamMap)=>{
          this.uuid = parseInt(params.get('uuid') || '0')
        })
        // 是编辑状态,设置标志符
        if(this.uuid) {
          this.isAdd = false
        }
        
        if(this.isAdd) {
          this.validateForm = this.fb.group({
            username: [null, [Validators.required]],
            position: [null, [Validators.required]]
          });
        } else {
          let current = (this.userInfo.filter((item: any) => item.uuid === this.uuid))[0] || {}
          // 信息回填
          this.validateForm = this.fb.group({
            username: [current.name, [Validators.required]],
            position: [current.position, [Validators.required]]
          })
        }
        
      }
    
      submitForm() {
        // 如果不符合提交,则报错
        if(!this.validateForm.valid) {
          Object.values(this.validateForm.controls).forEach((control: any) => {
            if(control?.invalid) {
              control?.markAsDirty();
              control?.updateValueAndValidity({ onlySelf: true });
            }
          })
          return
        }
    
        // 获取到表单的数据
        const data = this.validateForm.value
        // 新增用户
        if(this.isAdd) {
          
          let lastOne = (this.userInfo.length > 0 ? this.userInfo[this.userInfo.length-1] : {});
          this.userInfo.push({
            uuid: (lastOne.uuid ? (lastOne.uuid + 1) : 1),
            name: data.username,
            position: data.position
          })
          localStorage.setItem('users', JSON.stringify(this.userInfo))
        } else { // 编辑用户,更新信息
          let mapList = this.userInfo.map((item: any) => {
            if(item.uuid === this.uuid) {
              return {
                uuid: this.uuid,
                name: data.username,
                position: data.position
              }
            }
            return item
          })
          localStorage.setItem('users', JSON.stringify(mapList))
        }
      }
    
    }

    我们先设定一个标志符 isAdd,默认是新建用户;当 uuid 存在的时候,将其设置为 false 值,表示是编辑的状态,对内容进行表单的回填。提交表单的操作也是按照该标志符进行判断。我们直接对 localStorage 的信息进行变更,以保证同步列表信息。

    删除功能

    我们引入模态对话框进行询问是否删除。

    // user.component.ts
    
    // 删除
    delete(data: any) {
      this.modal.confirm({
        nzTitle: '<i>你想删除该用户?</i>',
        nzOnOk: () => {
          let users = JSON.parse(localStorage.getItem('users') || '[]');
          let filterList = users.filter((item: any) => item.uuid !== data.uuid);
          localStorage.setItem('users', JSON.stringify(filterList));
          this.list = filterList
        }
      });
    }

    6.png

    我们找到删除的数据,将其剔除,重新缓存新的用户数据,并更新 table 的用户列表数据。

    So,到此为止,我们顺利完成了一个简单的项目。我们用 Gif 图整体来看看。

    7.gif

    【完】

    更多编程相关知识,请访问:编程入门!!

    以上就是Angular + NG-ZORRO快速开发一个后台系统的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除
    专题推荐:Angular
    上一篇:react如何实现hooks?必须依赖 Fiber 么? 下一篇:Node更新了,一起看看Node18的新特性!
    20期PHP线上班

    相关文章推荐

    • 【活动】充值PHP中文网VIP即送云服务器• Angular怎么结合Git Commit进行版本处理• 聊聊Angular中怎么将迁移tslint至eslint• Angular学习之以Tooltip为例了解自定义指令• 聊聊怎么利用Angular+Jenkins展示构建版本• Angular利用service实现自定义服务(notification)
    1/1

    PHP中文网