跳转到主要内容

标签(标签)

资源精选(342) Go开发(108) Go语言(103) Go(99) angular(82) LLM(75) 大语言模型(63) 人工智能(53) 前端开发(50) LangChain(43) golang(43) 机器学习(39) Go工程师(38) Go程序员(38) Go开发者(36) React(33) Go基础(29) Python(24) Vue(22) Web开发(20) Web技术(19) 精选资源(19) 深度学习(19) Java(18) ChatGTP(17) Cookie(16) android(16) 前端框架(13) JavaScript(13) Next.js(12) 安卓(11) typescript(10) 资料精选(10) NLP(10) 第三方Cookie(9) Redwoodjs(9) LLMOps(9) Go语言中级开发(9) 自然语言处理(9) 聊天机器人(9) PostgreSQL(9) 区块链(9) mlops(9) 安全(9) 全栈开发(8) ChatGPT(8) OpenAI(8) Linux(8) AI(8) GraphQL(8) iOS(8) 软件架构(7) Go语言高级开发(7) AWS(7) C++(7) 数据科学(7) whisper(6) Prisma(6) 隐私保护(6) RAG(6) JSON(6) DevOps(6) 数据可视化(6) wasm(6) 计算机视觉(6) 算法(6) Rust(6) 微服务(6) 隐私沙盒(5) FedCM(5) 语音识别(5) Angular开发(5) 快速应用开发(5) 提示工程(5) Agent(5) LLaMA(5) 低代码开发(5) Go测试(5) gorm(5) REST API(5) 推荐系统(5) WebAssembly(5) GameDev(5) CMS(5) CSS(5) machine-learning(5) 机器人(5) 游戏开发(5) Blockchain(5) Web安全(5) Kotlin(5) 低代码平台(5) 机器学习资源(5) Go资源(5) Nodejs(5) PHP(5) Swift(5) 智能体(4) devin(4) Blitz(4) javascript框架(4) Redwood(4) GDPR(4) 生成式人工智能(4) Angular16(4) Alpaca(4) SAML(4) JWT(4) JSON处理(4) Go并发(4) kafka(4) 移动开发(4) 移动应用(4) security(4) 隐私(4) spring-boot(4) 物联网(4) nextjs(4) 网络安全(4) API(4) Ruby(4) 信息安全(4) flutter(4) 专家智能体(3) Chrome(3) CHIPS(3) 3PC(3) SSE(3) 人工智能软件工程师(3) LLM Agent(3) Remix(3) Ubuntu(3) GPT4All(3) 软件开发(3) 问答系统(3) 开发工具(3) 最佳实践(3) RxJS(3) SSR(3) Node.js(3) Dolly(3) 移动应用开发(3) 编程语言(3) 低代码(3) IAM(3) Web框架(3) CORS(3) 基准测试(3) Go语言数据库开发(3) Oauth2(3) 并发(3) 主题(3) Theme(3) earth(3) nginx(3) 软件工程(3) azure(3) keycloak(3) 生产力工具(3) gpt3(3) 工作流(3) C(3) jupyter(3) 认证(3) prometheus(3) GAN(3) Spring(3) 逆向工程(3) 应用安全(3) Docker(3) Django(3) R(3) .NET(3) 大数据(3) Hacking(3) 渗透测试(3) C++资源(3) Mac(3) 微信小程序(3) Python资源(3) JHipster(3) 大型语言模型(2) 语言模型(2) 可穿戴设备(2) JDK(2) SQL(2) Apache(2) Hashicorp Vault(2) Spring Cloud Vault(2) Go语言Web开发(2) Go测试工程师(2) WebSocket(2) 容器化(2) AES(2) 加密(2) 输入验证(2) ORM(2) Fiber(2) Postgres(2) Gorilla Mux(2) Go数据库开发(2) 模块(2) 泛型(2) 指针(2) HTTP(2) PostgreSQL开发(2) Vault(2) K8s(2) Spring boot(2) R语言(2) 深度学习资源(2) 半监督学习(2) semi-supervised-learning(2) architecture(2) 普罗米修斯(2) 嵌入模型(2) productivity(2) 编码(2) Qt(2) 前端(2) Rust语言(2) NeRF(2) 神经辐射场(2) 元宇宙(2) CPP(2) 数据分析(2) spark(2) 流处理(2) Ionic(2) 人体姿势估计(2) human-pose-estimation(2) 视频处理(2) deep-learning(2) kotlin语言(2) kotlin开发(2) burp(2) Chatbot(2) npm(2) quantum(2) OCR(2) 游戏(2) game(2) 内容管理系统(2) MySQL(2) python-books(2) pentest(2) opengl(2) IDE(2) 漏洞赏金(2) Web(2) 知识图谱(2) PyTorch(2) 数据库(2) reverse-engineering(2) 数据工程(2) swift开发(2) rest(2) robotics(2) ios-animation(2) 知识蒸馏(2) 安卓开发(2) nestjs(2) solidity(2) 爬虫(2) 面试(2) 容器(2) C++精选(2) 人工智能资源(2) Machine Learning(2) 备忘单(2) 编程书籍(2) angular资源(2) 速查表(2) cheatsheets(2) SecOps(2) mlops资源(2) R资源(2) DDD(2) 架构设计模式(2) 量化(2) Hacking资源(2) 强化学习(2) flask(2) 设计(2) 性能(2) Sysadmin(2) 系统管理员(2) Java资源(2) 机器学习精选(2) android资源(2) android-UI(2) Mac资源(2) iOS资源(2) Vue资源(2) flutter资源(2) JavaScript精选(2) JavaScript资源(2) Rust开发(2) deeplearning(2) RAD(2)

在开发Angular应用程序时,我非常喜欢Typescript。使用NestJS,您可以以与Angular非常相似的方式编写后端。

我偶然发现了这个库,发现它非常有趣,所以我想设置一个简单的测试项目。一般来说,我主要使用SQL数据库,因此我也将尝试Prisma将我们的数据存储在PostgreSQL中,并在前端和后端之间提供一个通用模型。

要开始使用NestJS,您必须安装npm包并运行CLI命令来创建新的应用程序。为了在NestJS项目中托管我们的Angular应用程序,我们还需要添加NestJS静态包。

** Install NestJS and create the Project.
npm install --save @nestjs/cli
nest new backend
npm install --save @nestjs/serve-static**Create our Angular application
cd backend
ng new ui

您已经可以看到CLI的实现与Angular非常相似。为了使NestJS能够托管我们的Angular应用程序,我们可以在后端的app.module.ts文件中添加对静态网站的引用。

@Module({
  imports: [ServeStaticModule.forRoot({
    rootPath: join(__dirname, '../../ui', 'dist/ui'),
  }),],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

 

我们可以参考Angular dist文件夹的位置。
**Build the angular code
cd ui
ng build**Start the nest server
cd ..
nest start --watch

现在我们已经运行了基本功能,我们可以设置模型了。我们将为专业驾驶的公里数创建一个简单的日志记录应用程序。我将在Prisma中完成这项工作,在那里我们可以创建一个模型,并自动生成客户端和数据库。

npm install prisma --save-dev
npx prisma init

这将创建一个“schema.prisma”文件,并添加一个.env文件,我们可以在其中配置到数据库的连接字符串。我将在这里使用PostgreSQL,但prisma也支持MySQL、SQL Server甚至MongoDB。在模式文件中,我在这里为DriveLog创建一个简单的模型。

model DriveLog {
  id          Int      @id @default(autoincrement())
  createdAt   DateTime @default(now())
  timestamp   DateTime  
  destination String?  
  odoStart  Int
  odoEnd    Int
  distance  Int?
}

我们将记录行程的时间和目的地,以及里程计的开始和结束值。

假设您已经正确配置了连接字符串,现在可以将模型推送到数据库中。这也将自动生成客户端代码。

**Push the model to the DB and generate a PrismaClient.
npx prisma db push

因为我们想利用NestJS的注入功能,这些功能的工作方式与Angular非常相似。我们将创建一个PrismaService来包装生成的客户端代码。

**Generate an empty service for NestJS
nest generate service prisma


import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient
  implements OnModuleInit {

  async onModuleInit() {
    await this.$connect();
  }

  async enableShutdownHooks(app: INestApplication) {
    this.$on('beforeExit', async () => {
      await app.close();
    });    
  }
}

我们在这里引用生成的PrismaClient,并确保我们可以从应用程序访问它,而不必每次都创建新的客户端。

现在,我们可以设置后端逻辑来创建CRUD操作,并将其添加到app.service文件中。我们将设置一个获取全部、保存和删除操作。

import { Injectable } from '@nestjs/common';
import { DriveLog } from '@prisma/client';
import { PrismaService } from './prisma/prisma.service';

@Injectable()
export class AppService {

  constructor(private prisma: PrismaService) { }

  async getAll(): Promise<DriveLog[]> {
    return await this.prisma.driveLog.findMany();
  }

  async save(log: DriveLog) {
    let distance = log.odoEnd - log.odoStart;
    if(log.id){
      await this.prisma.driveLog.update({ where: {id: log.id}, data: { timestamp: new Date(log.timestamp), destination: log.destination, odoStart: log.odoStart, odoEnd: log.odoEnd, distance: distance }} );
    }else{
      await this.prisma.driveLog.create({ data: { timestamp: new Date(log.timestamp), destination: log.destination, odoStart: log.odoStart, odoEnd: log.odoEnd, distance: distance } });
    }
  }

  async delete(logId: number) {
    await this.prisma.driveLog.delete({ where: { id: logId } })
  }
}

 

我们将根据给定里程表值的开始-结束值计算保存操作中行驶的距离。

接下来,我们需要设置控制器,以便向Angular应用程序公开一些端点。

import { Body, Controller, Delete, Get, Param, Post } from '@nestjs/common';
import { DriveLog } from '@prisma/client';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private appService: AppService) {}

  @Get("api/logs")
  async getAll(): Promise<DriveLog[]> {
    return await this.appService.getAll();
  }

  @Post("api/logs")
  async create(@Body()log: DriveLog): Promise<void> {
    await this.appService.save(log);
  }

  @Delete("api/logs/:log")
  async delete(@Param('log') log: string ): Promise<void> {
    await this.appService.delete(parseInt(log));
  }
}

 

现在我们已经准备好设置Angular应用程序了。首先确保我们导入HttpClientModule和FormsModule,这样我们就可以创建一个简单的表单并调用我们刚刚在nest中创建的端点。

<ul>
  <li *ngFor="let log of logs">
    {{log.timestamp |date}} - {{log.destination}} - {{log.distance}}km 
    <button (click)="deleteLog(log.id)">X</button>
    <button (click)="edit(log)">Edit</button>
  </li>
</ul>
<form>
  <input type="date" [(ngModel)]="newLog.timestamp" name="timestamp" placeholder="timestamp" >
  <input type="text" [(ngModel)]="newLog.destination" name="destination" placeholder="destination">
  <input type="number" [(ngModel)]="newLog.odoStart" name="odoStart" placeholder="start (km)" >
  <input type="number" [(ngModel)]="newLog.odoEnd" name="odoEnd" placeholder="end (km)" >
  <button (click)="save()">{{ newLog.id ? 'Save' : 'Add' }}</button>
</form>

 

在app.component.html中,我们创建了一个简单的表单,可以在其中查看、添加、更新和删除我们的旅行日志。

我们现在可以为app.component设置控制器来调用NestJS端点。

import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
import { DriveLog } from '@prisma/client';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  logs: DriveLog[] = []
  newLog: DriveLog = <DriveLog>{}

  constructor(private http: HttpClient) {
    this.getAll();
  }

  getAll() {
    this.http.get<DriveLog[]>("api/logs").subscribe(l => this.logs = l)
  }

  edit(log: DriveLog){
    this.newLog = log;
    this.newLog.timestamp = new Date(log.timestamp);
  }
 
  save() {
    this.http.post("api/logs", this.newLog).subscribe(() => this.getAll());
    this.newLog = <DriveLog>{};
  }

  deleteLog(id: number){
    this.http.delete(`api/logs/${id}`).subscribe(() => this.getAll());
  }
}

 

请注意,我们可以在这里简单地引用从prisma生成的DriveLog类型。

现在我们只需要构建我们的Angular代码,当再次运行NestJS应用程序时,我们将使表单正常工作。

这(对我来说)的好处在于,我可以从前端到后端编写应用程序,包括数据库逻辑,而无需更改编程语言,也无需维护前端和后端之间的工作方式。

文章链接