让我们更新我们的代码库,然后进入一个新的级别,让我们将我们的资源嵌入模型!
这个想法
让我们看一下以下代码:
// src/users/controllers/users-list.ts
import User from "../models/user";
export default async function usersList() {
const users = await User.list();
return {
users,
};
}
这基本上将返回一系列模型,并将返回每个模型中列出的整个属性,这太丑陋了,从这个意义上讲,如果模型没有资源,我们需要将我们的模型与我们的资源联系起来,然后我们只返回data
而不是整个型号。
Tojson方法
让我们首先实现简单的部分,让我们在base-model
文件中创建一个toJSON
方法,还记得吗?我们埋在模型文件夹中的模型,让我们添加一种新方法:
// src/core/database/model/base-model.ts
// ...
export default abstract class BaseModel {
/**
* Prepare model for response
*/
public async toJSON() {
return (this as any).data;
}
}
为什么我们添加any
,因为CrudModel
对此一无所知,我们在Model
类中添加了该属性,因此我们需要告诉Typescript可以使用它。
,而且由于下一步添加资源。
添加资源
该资源将作为static
属性添加,为什么?好吧,因为我们可以访问模型的资源而无需创建模型实例,例如:
const UserResource = User.resource;
return {
user: new UserResource({
id: 1,
name: 'Hasan',
})
};
我知道这很奇怪,为什么不直接打电话给UserResource
类,好吧,您是对的,但是让我们坚持这个想法,我更喜欢它。
返回我们的代码,让我们将resource
属性添加到我们的BaseModel
类:
// src/core/database/model/base-model.ts
import Resource from 'core/resources/resource';
// ...
export default abstract class BaseModel {
/**
* Resource class
*/
public static resource: typeof Resource;
// ...
}
现在让我们更新使用资源的toJSON
方法:
// src/core/database/model/base-model.ts
import Resource from 'core/resources/resource';
// ...
export default abstract class BaseModel {
/**
* Resource class
*/
public static resource: typeof Resource;
/**
* Prepare model for response
*/
public async toJSON() {
// get static resource class
const resource = this.getStaticProperty("resource");
// if the model has a resource class
if (resource) {
// then return the resource instance and call `toJSON` method
return await new resource(this).toJSON();
}
// otherwise return the data object
return (this as any).data;
}
}
就是这样!现在我们可以使用我们的用户模型尝试
// src/app/users/models/user.ts
import Auth from "core/auth/models/auth";
import castPassword from "core/database/casts/cast-password";
import { Casts, Document } from "core/database/model/types";
import UserResource from "../resources/user-resource";
export default class User extends Auth {
/**
* Collection name
*/
public static collectionName = "users";
/**
* Resource
*/
public static resource = UserResource;
/**
* Get user type
*/
public get userType(): string {
return "user";
}
/**
* {@inheritDoc}
*/
public defaultValue: Document = {
isActive: true,
isEmailVerified: false,
isPhoneVerified: false,
};
protected casts: Casts = {
isActive: "boolean",
isPhoneVerified: "boolean",
joinDate: "date",
password: castPassword,
};
}
现在,我们的用户模型与UserResource
类自动链接。
用法
现在让我们看看魔术发生了,让我们更新我们的users-list
控制器:
// src/users/controllers/users-list.ts
import User from "../models/user";
export default async function usersList() {
const users = await User.list();
return {
users,
};
}
相同的确切代码,但是这次您将在响应中看到它是从资源而非模型返回的,并且要确保其工作正常,让我们在我们的用户资源中添加boot方法,然后将自定义属性添加到最终输出。
// src/app/users/resources/user-resource.ts
import Resource from "core/resources/resource";
export default class UserResource extends Resource {
/**
* {@inheritDoc}
*/
protected async boot() {
this.set('outputFromUserResource', true);s
}
}
现在您应该看到这样的东西:
{
"users": [
{
"outputFromUserResource": true,
"isActive": true,
"isPhoneVerified": false,
"name": "John Doe",
"email": "hassanzohdy@gmail.com",
"image": "http://127.0.0.1:3000/uploads/users/my-image.jpg"
},
{
"outputFromUserResource": true,
"isActive": true,
"isPhoneVerified": false,
"name": "John Doe",
"email": "hassanzohdy@gmail.com",
"image": "http://127.0.0.1:3000/uploads/users/my-image.jpg"
},
{
"outputFromUserResource": true,
"isActive": true,
"isPhoneVerified": false,
"name": "John Doe",
"email": "hassanzohdy@gmail.com",
"image": "http://127.0.0.1:3000/uploads/users/my-image.jpg"
},
{
"outputFromUserResource": true,
"isActive": true,
"isPhoneVerified": false,
"name": "John Doe",
"email": "hassanzohdy@gmail.com",
"image": "http://127.0.0.1:3000/uploads/users/my-image.jpg"
},
{
"outputFromUserResource": true,
"isActive": true,
"isPhoneVerified": false,
"name": "John Doe",
"email": "hassanzohdy@gmail.com",
"image": "http://127.0.0.1:3000/uploads/users/my-image.jpg"
},
{
"outputFromUserResource": true,
"isActive": true,
"isPhoneVerified": false,
"name": "John Doe",
"email": "hassanzohdy@gmail.com",
"image": "http://127.0.0.1:3000/uploads/users/my-image.jpg"
}
]
}
就是这样!
- 结论
我们在本教程中看到了如何在响应中返回时如何操纵模型,以及如何将资源链接到模型。
â•给我买一杯咖啡。
如果您喜欢我的文章并看到对您有用,则可以buy me a coffee,它将帮助我继续前进并继续创建更多内容。
ð项目存储库
您可以在Github
上找到此项目的最新更新ð加入我们的社区
加入我们的社区Discord获得帮助和支持(节点JS 2023频道)。
ð视频课程(阿拉伯语)
如果您想以视频格式学习此课程,则可以在Youtube上找到该课程,该课程是阿拉伯语。
ð奖励内容ð
您可能会看这些文章,这肯定会提高您的知识和生产力。
一般主题
- Event Driven Architecture: A Practical Guide in Javascript
- Best Practices For Case Styles: Camel, Pascal, Snake, and Kebab Case In Node And Javascript
- After 6 years of practicing MongoDB, Here are my thoughts on MongoDB vs MySQL
软件包和库
- Collections: Your ultimate Javascript Arrays Manager
- Supportive Is: an elegant utility to check types of values in JavaScript
- Localization: An agnostic i18n package to manage localization in your project
React JS软件包
课程(文章)