## MVC(模型-視圖-控制器)
`Nest` 默認使用 `Express` 庫,因此,在 `Express` 中使用 `MVC` (模型 - 視圖 - 控制器)模式的每一種技術同樣適用于 `Nest` 。首先,讓我們使用 `CLI` 工具搭建一個簡單的 `Nest` 應用程序:
```bash
$ npm i -g @nestjs/cli
$ nest new project
```
為了創建一個簡單的 `MVC` 應用程序,我們必須安裝一個[模板引擎](http://expressjs.com/en/guide/using-template-engines.html):
```bash
$ npm install --save hbs
```
我們決定使用 [hbs](https://github.com/pillarjs/hbs#readme) 引擎,但您可以使用任何符合您要求的內容。安裝過程完成后,我們需要使用以下代碼配置 `express` 實例:
> main.ts
```typescript
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.useStaticAssets(join(__dirname, '..', 'public'));
app.setBaseViewsDir(join(__dirname, '..', 'views'));
app.setViewEngine('hbs');
await app.listen(3000);
}
bootstrap();
```
我們告訴 `express`,該 `public` 目錄將用于存儲靜態文件, `views` 將包含模板,并且 `hbs` 應使用模板引擎來呈現 `HTML` 輸出。
`app.useStaticAssets` 還支持第二個參數來設置虛擬目錄。
```typescript
app.useStaticAssets(join(__dirname, '..', 'public'), {
prefix: '/static',
});
```
### 模板渲染
現在,讓我們在該文件夾內創建一個 `views` 目錄和一個 `index.hbs` 模板。在模板內部,我們將打印從控制器傳遞的 `message`:
> index.hbs
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>App</title>
</head>
<body>
{{ message }}
</body>
</html>
```
然后, 打開 `app.controller` 文件, 并用以下代碼替換 `root()` 方法:
> app.controller.ts
```typescript
import { Get, Controller, Render } from '@nestjs/common';
@Controller()
export class AppController {
@Get()
@Render('index')
root() {
return { message: 'Hello world!' };
}
}
```
在這個代碼中,我們指定模板使用`@Render()`裝飾器,同時將路徑處理器方法的返回值被傳遞給要渲染的模板。注意,該返回值是一個包含`message`屬性的對象,和我們之前創建模板中的`message`占位符對應。
在應用程序運行時,打開瀏覽器訪問 `http://localhost:3000/` 你應該看到這個 `Hello world!` 消息。
### 動態模板渲染
如果應用程序邏輯必須動態決定要呈現哪個模板,那么我們應該使用 `@Res()`裝飾器,并在路由處理程序中提供視圖名,而不是在 `@Render()` 裝飾器中:
> 當 `Nest` 檢測到 `@Res()` 裝飾器時,它將注入特定于庫的響應對象。我們可以使用這個對象來動態呈現模板。在[這里](http://expressjs.com/en/api.html)了解關于響應對象 `API` 的更多信息。
> app.controller.ts
```typescript
import { Get, Controller, Render } from '@nestjs/common';
import { Response } from 'express';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
root(@Res() res: Response) {
return res.render(this.appService.getViewName(), { message: 'Hello world!' });
}
}
```
[這里](https://github.com/nestjs/nest/tree/master/sample/15-mvc)有一個可用的例子。
### Fastify
如本章所述,我們可以將任何兼容的 `HTTP` 提供程序與 `Nest` 一起使用。比如 [Fastify](https://github.com/fastify/fastify) 。為了創建具有 `fastify` 的 `MVC` 應用程序,我們必須安裝以下包:
```bash
$ npm i --save fastify point-of-view handlebars
```
接下來的步驟幾乎涵蓋了與 `express` 庫相同的內容(差別很小)。安裝過程完成后,我們需要打開 `main.ts` 文件并更新其內容:
> main.ts
```typescript
import { NestFactory } from '@nestjs/core';
import { NestFastifyApplication, FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import { join } from 'path';
async function bootstrap() {
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
app.useStaticAssets({
root: join(__dirname, '..', 'public'),
prefix: '/public/',
});
app.setViewEngine({
engine: {
handlebars: require('handlebars'),
},
templates: join(__dirname, '..', 'views'),
});
await app.listen(3000);
}
bootstrap();
```
Fastify 的`API` 略有不同,但這些方法調用背后的想法保持不變。使用 Fastify 時一個明顯的需要注意的區別是傳遞到 `@Render()` 裝飾器中的模板名稱包含文件擴展名。
> app.controller.ts
```typescript
import { Get, Controller, Render } from '@nestjs/common';
@Controller()
export class AppController {
@Get()
@Render('index.hbs')
root() {
return { message: 'Hello world!' };
}
}
```
在應用程序運行時,打開瀏覽器并導航至 `http://localhost:3000/` 。你應該看到這個 `Hello world!` 消息。
[這里](https://github.com/nestjs/nest/tree/master/sample/17-mvc-fastify)有一個可用的例子。
- 介紹
- 概述
- 第一步
- 控制器
- 提供者
- 模塊
- 中間件
- 異常過濾器
- 管道
- 守衛
- 攔截器
- 自定義裝飾器
- 基礎知識
- 自定義提供者
- 異步提供者
- 動態模塊
- 注入作用域
- 循環依賴
- 模塊參考
- 懶加載模塊
- 應用上下文
- 生命周期事件
- 跨平臺
- 測試
- 技術
- 數據庫
- Mongo
- 配置
- 驗證
- 緩存
- 序列化
- 版本控制
- 定時任務
- 隊列
- 日志
- Cookies
- 事件
- 壓縮
- 文件上傳
- 流式處理文件
- HTTP模塊
- Session(會話)
- MVC
- 性能(Fastify)
- 服務器端事件發送
- 安全
- 認證(Authentication)
- 授權(Authorization)
- 加密和散列
- Helmet
- CORS(跨域請求)
- CSRF保護
- 限速
- GraphQL
- 快速開始
- 解析器(resolvers)
- 變更(Mutations)
- 訂閱(Subscriptions)
- 標量(Scalars)
- 指令(directives)
- 接口(Interfaces)
- 聯合類型
- 枚舉(Enums)
- 字段中間件
- 映射類型
- 插件
- 復雜性
- 擴展
- CLI插件
- 生成SDL
- 其他功能
- 聯合服務
- 遷移指南
- Websocket
- 網關
- 異常過濾器
- 管道
- 守衛
- 攔截器
- 適配器
- 微服務
- 概述
- Redis
- MQTT
- NATS
- RabbitMQ
- Kafka
- gRPC
- 自定義傳輸器
- 異常過濾器
- 管道
- 守衛
- 攔截器
- 獨立應用
- Cli
- 概述
- 工作空間
- 庫
- 用法
- 腳本
- Openapi
- 介紹
- 類型和參數
- 操作
- 安全
- 映射類型
- 裝飾器
- CLI插件
- 其他特性
- 遷移指南
- 秘籍
- CRUD 生成器
- 熱重載
- MikroORM
- TypeORM
- Mongoose
- 序列化
- 路由模塊
- Swagger
- 健康檢查
- CQRS
- 文檔
- Prisma
- 靜態服務
- Nest Commander
- 問答
- Serverless
- HTTP 適配器
- 全局路由前綴
- 混合應用
- HTTPS 和多服務器
- 請求生命周期
- 常見錯誤
- 實例
- 遷移指南
- 發現
- 誰在使用Nest?