我们已经在上一章中定义了输出类型,现在让我们看看如何定义自定义输出处理程序。
目的
有时我们想自定义某些值的最终输出,例如使用uploadsUrl
为上传文件生成完整的URL,因为我们仅存储在数据库中uploads目录的相对路径,因此我们需要返回完整的URL上传文件。
自定义输出处理程序
这是我们可以定义自定义输出处理程序的地方,让我们以示例来阐明所有内容,让我们更新我们的用户资源类。
// 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,
};
}
当然,这是不起作用的,因为我们没有将uploadsUrl
的呼叫转换为函数调用,所以让我们在基本资源类中进行
// 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 (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语句以检查值类型,如果是一个函数,我们将其调用并将值传递给它,然后我们返回结果。
现在,当我们检查响应时,我们会看到这样的东西。
"image": "http://127.0.0.1:3000/uploads/users/my-image.jpg"
正如我们仅在资源对象中所拥有的,users/my-image.jpg
,我们要返回完整的URL。
- 结论
在本章中,我们添加了另一个功能,该功能是使用自定义输出处理程序来突变我们想要的最终输出值,这将使我们有很大的灵活性来自定义最终输出。
在下一章中,我们将看到如何使用嵌套资源,另一个资源内的资源!请敬请期待。
â•给我买一杯咖啡。
如果您喜欢我的文章并看到对您有用,则可以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软件包
课程(文章)