87-Nodejs课程2023:资源:模型中的资源
#typescript #node #mongodb #fastify

让我们更新我们的代码库,然后进入一个新的级别,让我们将我们的资源嵌入模型!

这个想法

让我们看一下以下代码:

// 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上找到该课程,该课程是阿拉伯语。

ð奖励内容ð

您可能会看这些文章,这肯定会提高您的知识和生产力。

一般主题

软件包和库

React JS软件包

课程(文章)