Maison  >  Article  >  interface Web  >  Angular + NG-ZORRO développent rapidement un système backend

Angular + NG-ZORRO développent rapidement un système backend

青灯夜游
青灯夜游avant
2022-04-21 10:45:463914parcourir

Cet article partagera avec vous une application pratique de Angular pour apprendre à développer rapidement un système backend en utilisant angualr combiné avec ng-zorro. J'espère que cela sera utile à tout le monde !

Angular + NG-ZORRO développent rapidement un système backend

Ces derniers jours, nous avons beaucoup appris sur angular, et cette fois nous avons un petit produit fini. angular 的知识点了,这次我们来个小成品。

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

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

  • 欢迎页面
  • 用户列表
  • 用户新增
  • 用户修改
  • 用户删除

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

说干咱就干。

结合 ng-zorro

angular 比较流行的 ui 框架有:

  • Angular Material 官方指定 UI 框架
  • NG-ZORRO,又名 Ant Design of Angular 国内比较流行的 UI 框架

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

Angular + NG-ZORRO développent rapidement un système backend

我们重新使用 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 的页面看到下图内容。

Angular + NG-ZORRO développent rapidement un système backend

Not Bad, Bro.

配置路由

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

思路:

  • 先添加页面 user 用户的列表页面,使用 ng-zorrotable 组件

  • 用户的新增和更改页面可以共用同一个页面,使用 ng-zorroform 组件

  • 页面删除功能直接使用弹窗提示,使用 ng-zorromodal 组件

  • ng-zorro 组件按需引入

  • 调整路由文件

按照思路,我们得在 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 ? &#39;menu-unfold&#39; : &#39;menu-fold&#39;"
            ></i>
        </span>
      </div>
    </nz-header>
    <nz-content>
      <div class="inner-content">
        <router-outlet></router-outlet>
      </div>
    </nz-content>
  </nz-layout>
</nz-layout>

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

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

Angular + NG-ZORRO développent rapidement un système backend

完成用户列表

接下来完成用户列表的骨架,因为使用了 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 &#39;@angular/core&#39;;
import { UserService } from &#39;src/app/services/user.service&#39;;

@Component({
  selector: &#39;app-user&#39;,
  templateUrl: &#39;./user.component.html&#39;,
  styleUrls: [&#39;./user.component.scss&#39;]
})
export class UserComponent implements OnInit {

  public list: any = []

  constructor(
    private readonly userService: UserService
  ) { }

  ngOnInit(): void {
    if(localStorage.getItem(&#39;users&#39;)) {
      let obj = localStorage.getItem(&#39;users&#39;) || &#39;{}&#39;
      this.list =  JSON.parse(obj)
    } else {
      this.getList()
    }
  }

  // 获取用户列表
  getList() {
    this.userService.getUserList().subscribe({
      next: (data: any) => {
        localStorage.setItem(&#39;users&#39;, JSON.stringify(data.users))
        this.list = data.users
      },
      error: (error: any) => {
        console.log(error)
      }
    })
  }

}

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

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

Angular + NG-ZORRO développent rapidement un système backend

新增用户和编辑用户

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

我们在 html

angualr se combine avec ng-zorro pour développer rapidement et de manière standardisée un système backend. [Recommandations de didacticiel associées : "

Tutoriel angulaire

"]

Angular + NG-ZORRO développent rapidement un système backendLes fonctions du système incluent les éléments suivants :

  • Page d'accueil
  • Liste des utilisateurs
  • Ajout d'utilisateurs
  • Modification d'utilisateur
  • Suppression d'utilisateur
🎜Tous les services utilisent des données simulées. 🎜🎜Faisons ce que vous dites. 🎜🎜Combiné avec ng-zorro🎜🎜angular Le ui le plus populaire code > Les frameworks incluent : 🎜
  • Angular Material est un framework d'interface utilisateur officiellement désigné
  • NG-ZORRO, également connu sous le nom de Ant Design of Angular, un framework d'interface utilisateur national populaire
🎜Ant Design Je pense que les personnes qui font du développement front-end le connaissent. Nous le combinons donc ici avec le framework NG-ZORRO. Si vous connaissez la version Vue ou React de Ant Design, je pense que vous pouvez vous connecter de manière transparente~🎜🎜Angular + NG-ZORRO développent rapidement un système backend🎜🎜Nous réutilisons angular-cli Générer un projet ng-zorro. 🎜🎜Ajouter ng-zorro est très simple : entrez dans le répertoire racine ng-zorro et exécutez ng add ng-zorro-antd . 🎜
🎜Bien sûr, vous pouvez également exécuter npm install ng-zorro-antd pour l'ajouter, mais ce n'est pas recommandé. 🎜
🎜Combiné avec ng-zorro Une fois terminé, nous exécutons le projet npm run start, vous serez sur http://localhost:4200 code> page, voir l'image suivante. 🎜🎜Angular + NG-ZORRO développent rapidement un système backend🎜🎜Pas mal, frérot.🎜🎜Configuration du routage🎜🎜Nous l'avons changé en hash routage, et ajouter le routage utilisateur, l'échafaudage l'a fait pour nous, nous n'avons besoin que de quelques modifications mineures. 🎜🎜Idée : 🎜<ul style="list-style-type: disc;"> <li>🎜Ajoutez d'abord la page <code>user à la page de liste des utilisateurs, utilisez ng-zorro Dans le composant table🎜
  • 🎜les pages nouvelles et modifiées de l'utilisateur peuvent partager la même page, utilisez ng-zorro dans le formulaire > composant🎜
  • 🎜La fonction de suppression de page utilise directement des invites contextuelles, en utilisant le composant modal dans ng-zorro🎜
  • 🎜Introduire les composants ng-zorro selon les besoins🎜
  • 🎜Ajuster les fichiers de routage🎜
  • 🎜Selon l'idée, nous devons ajouter ng-zorro introduit : 🎜
    // 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]="&#39;primary&#39;">确认</button>
    </form>
    🎜Principe simple et facile à comprendre, nous n'utilisons pas de enfants ici pour l'imbrication des itinéraires : 🎜
    // user-info.component.ts
    
    import { Component, OnInit } from &#39;@angular/core&#39;;
    import { FormBuilder, FormGroup, Validators } from &#39;@angular/forms&#39;;
    import { ActivatedRoute, ParamMap } from &#39;@angular/router&#39;;
    
    @Component({
      selector: &#39;app-user-info&#39;,
      templateUrl: &#39;./user-info.component.html&#39;,
      styleUrls: [&#39;./user-info.component.scss&#39;]
    })
    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(&#39;users&#39;) || &#39;[]&#39;)
        this.route.paramMap.subscribe((params: ParamMap)=>{
          this.uuid = parseInt(params.get(&#39;uuid&#39;) || &#39;0&#39;)
        })
        // 是编辑状态,设置标志符
        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(&#39;users&#39;, 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(&#39;users&#39;, JSON.stringify(mapList))
        }
      }
    
    }
    🎜Changer de menu🎜🎜Le menu généré à l'aide de l'échafaudage ne correspond pas aux fonctions que nous devons développer. Ajustons-le. 🎜
    // user.component.ts
    
    // 删除
    delete(data: any) {
      this.modal.confirm({
        nzTitle: &#39;<i>你想删除该用户?</i>&#39;,
        nzOnOk: () => {
          let users = JSON.parse(localStorage.getItem(&#39;users&#39;) || &#39;[]&#39;);
          let filterList = users.filter((item: any) => item.uuid !== data.uuid);
          localStorage.setItem(&#39;users&#39;, JSON.stringify(filterList));
          this.list = filterList
        }
      });
    }
    🎜Affichage du menu, si nous devons gérer les autorisations, nous avons besoin que le backend coopère avec le transfert de valeur, puis nous afficherons le menu d'autorisation correspondant sur la page🎜
    🎜Après l'avoir remplacé par Avec le code ci-dessus, le squelette de base obtenu est le suivant : 🎜🎜3. png🎜🎜Complétez la liste des utilisateurs🎜🎜Ensuite, complétez le squelette de la liste des utilisateurs , parce que le framework UI est utilisé , il est extrêmement pratique pour nous d'écrire : 🎜🎜Obtenir la liste des utilisateurs🎜rrreee🎜Nous avons simulé certaines données dans les assets code> dossier <code>user .json :🎜rrreee🎜Après avoir écrit le service, nous appelons pour obtenir les données de l'utilisateur :🎜rrreee🎜Comme aucun service back-end n'est introduit, nous utilisons ici localstorage pour enregistrer l’état. 🎜🎜Après avoir complété ce qui précède, nous obtenons les informations de la liste comme suit : 🎜🎜<img src="https://img.php.cn/upload/image/234/426/447/1650508770904440.png" title="1650508770904440 .png" alt="Angular + NG-ZORRO développent rapidement un système backend">🎜🎜<strong>Ajouter des utilisateurs et modifier des utilisateurs</strong>🎜🎜Nous créons simplement un formulaire qui ne contient que deux champs, à savoir <code>nom et position. Ces deux fonctions partagent un formulaire~🎜🎜On ajoute en html :🎜rrreee🎜La page ressemble à ceci :🎜🎜🎜🎜

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

    // user-info.component.ts
    
    import { Component, OnInit } from &#39;@angular/core&#39;;
    import { FormBuilder, FormGroup, Validators } from &#39;@angular/forms&#39;;
    import { ActivatedRoute, ParamMap } from &#39;@angular/router&#39;;
    
    @Component({
      selector: &#39;app-user-info&#39;,
      templateUrl: &#39;./user-info.component.html&#39;,
      styleUrls: [&#39;./user-info.component.scss&#39;]
    })
    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(&#39;users&#39;) || &#39;[]&#39;)
        this.route.paramMap.subscribe((params: ParamMap)=>{
          this.uuid = parseInt(params.get(&#39;uuid&#39;) || &#39;0&#39;)
        })
        // 是编辑状态,设置标志符
        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(&#39;users&#39;, 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(&#39;users&#39;, JSON.stringify(mapList))
        }
      }
    
    }

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

    删除功能

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

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

    Angular + NG-ZORRO développent rapidement un système backend

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

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

    Angular + NG-ZORRO développent rapidement un système backend

    【完】

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

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer