在本文中,我们将查看如何将资源用作输出类型以及如何实现。
目的
为什么我们需要分配给resource
类型的输出密钥?好吧,因为我们使用的是mongodb,这意味着可以将文档存储在另一个文档中的单个键中,例如,我们可以将createdBy
对象存储在任何文档中(我们以后会做),依此类推。
因此,我们需要映射该createdBy
对象以使用其适当的资源来制作适当的响应输出。
我们将学习如何使用两件事,检查变量是否为类型类别,也是部分递归,这意味着可以自我调用的类/函数(以某种方式)。
实施之前
我们将在我们的Resource
类中添加一个新功能,该功能允许输出为资源,这要求我们添加对valueType
的支票以检查它是否是Resource
类型,所以我想向您展示如何检查变量是否是类的类型(类本身而不是对象是其实例)。
// some-file.ts
class MyClass {
}
const A = MyClass;
// check if A is a `MyClass` type
if (A.prototype instanceof MyClass) {
// A is a MyClass type
}
我们在这里使用prototype
检查该类是否是另一类的实例,因此我们可以使用它来检查valueType
是否是Resource
类型。
因此,我们可以说如果要检查变量是否为class
类型,我们使用prototype
,如果要检查变量是否是类的对象/实例,我们直接使用instanceof
。
执行
现在让我们看看如何做到这一点。
这很简单,我们只是分配给输出密钥,假设createdBy
UserResource
类型的值,在我们的toJSON
中,我们将添加另一个检查,如果给定值类型为type a Resource
,那么我们将传递数据对此,否则我们将完全跳过密钥。
// src/core/resources/resource.ts
import { get } from "@mongez/reinforcements";
// this will be used to skip the output property if it is missing from the given resource
const missingKey = Symbol("missing");
export default class Resource {
/**
* Constructor
*/
public constructor(protected resource: any = {}) {
//
}
/**
* Output shape
*/
protected output: any = {};
/**
* {@inheritDoc}
*/
public toJSON() {
// final output
const data: Record<string, any> = {};
// loop through the output property
for (const key in this.output) {
// get the value type
const valueType = this.output[key];
// get the value, and also make sure to skip the output property if it is missing from the given resource
let value = get(this.resource, key, missingKey);
// skip the output property if it is missing from the given resource
if (value === missingKey) {
continue;
}
if (typeof valueType === "string") {
// cast the value
value = this.cast(value, valueType);
} else if (valueType.prototype instanceOf Resource) {
// if the value type is a resource, then pass the value to it
value = new valueType(value).toJSON();
} else if (typeof valueType === "function") {
// call the custom output handler
value = valueType(value);
}
// just for now sett the output value to the data
data[key] = value;
}
return data;
}
/**
* Builtin casts
*/
protected cast(value: any, type: string) {
switch (type) {
case "number":
return Number(value);
case "float":
case "double":
return parseFloat(value);
case "int":
case "integer":
return parseInt(value);
case "string":
return String(value);
case "boolean":
return Boolean(value);
default:
return value;
}
}
}
在这里,我们只是添加了一些if语句,该语句正在检查值类型是否为Resource
类型,如果是的,则我们将其传递给它,否则我们将完全跳过密钥。
现在我们可以更新我们的UserResource
类
// src/app/users/resources/user-resource.ts
import Resource from 'core/resources/resource';
import { uploadsUrl } from 'core/utils/urls';
export default class UserResource extends Resource {
/**
* Output shape
*/
protected output: any = {
id: 'number',
name: 'string',
email: 'string',
age: 'number',
avatar: uploadsUrl,
createdBy: UserResource,
};
}
这应该可以与您合作,将数据传递给名为createdBy
的键并传递给对象。
这里的重点是使用UserResource
类映射该数据为正确的输出。
这也称为Recursive Resource
,因为我们使用相同的资源将数据映射到输出。
- 结论
我们刚刚学会了如何实现彼此内部资源的递归呼吁,以及如何检查变量是否为类。
â•给我买一杯咖啡。
如果您喜欢我的文章并看到对您有用,则可以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软件包
课程(文章)