如何在 FeathersJS 服务扩展中使用 app.service('myService')?

How to use app.service('myService') inside a FeathersJS service extension?

我正在尝试为我的 FeathersJS 应用程序中名为 properties 的服务扩展 find() 方法。

我需要在 find() 返回的所有记录中附加一个数组,其中包含来自另一个名为 propertyadds 的服务的整数。这意味着我需要更改

的回复
{
  "total": 2973,
  "limit": 10,
  "skip": 0,
  "data": [
    {
      "id": 1,
      ...
    },
    {
      "id": 2,
      ...
    }
    ...
  ]
}

{
  "total": 2973,
  "limit": 10,
  "skip": 0,
  data: [
    {
      "id": 1,
      ...
      "additionals": [10,20,30]
    },
    {
      "id": 2,
      ...
      "additionals": [12,25,33]
    }
    ...
  ]
}

additionals 中的值来自服务 propertyadds,它管理着 table like

| property_id | additional_id |
|-------------|---------------|
|      1      |       10      |
|      1      |       20      |
|      1      |       30      |
|      2      |       12      |
|      2      |       25      |
|      2      |       33      |
|-------------|---------------|

我最初的想法是像这样扩展 properties 服务

const { Service } = require('feathers-sequelize');

exports.Properties = class Properties extends Service {
  async find(data,params) {
      let newResponse = await super.find(data,params);
      let newData = newResponse.data.map(async pr => {
          pr.additionals = await app.service('propertyadds').find({
              properti_id: pr.id
          })
          return pr;
      })
      return {
          total: newResponse.total,
          limit: newResponse.limit,
          skip: newResponse.skip,
          data: newData
      }
  }
};

问题是我在 src/services/properties/properties.class.js 中没有 app 并且(我是 FeathersJS 的新手)我不知道如何得到它。

我需要什么才能让有效的 app const 访问此模块内的所有服务?

我不知道羽毛续集,但根据 doc

对于调用app.listen之前注册的服务,每个注册服务的设置函数在调用app.listen...[=17=时被调用]

通过从 Service 继承(我不知道这是否是标准方法),也许 Service 实现 setup,您可以访问 this.app Properties::find()

以内

如果你没有,那就写吧:

async find(data,params) {
...
}
async setup(app, path){
  await super.setup && super.setup(app, path)
  // for now no setup on Service
  // should Service adds a setup, it is unlikely that it wraps app to a 
  // whole new object and assigns it to this, so we can still
  // assign app to this with a relative confidence
  this.app = app
}

实际上,当我访问 src/services/properties.service.js 并发现这一行时,解决方案就实现了

app.use('/properties', new Properties(options, app));

因此,服务 properties 实际上在其创建过程中接收了一个 app 对象。

学习这个让我看到了正确的解决方案,写在 src/services/properties/properties.class.js 中是这样的:

const { Service } = require('feathers-sequelize');

exports.Properties = class Properties extends Service {

    constructor(options, app) {
        super(options, app);
        this.app = app;
    }

    async find(data, params) {
        let oldRes = await super.find(data, params);
        let newResData = oldRes.data.map(async pr => {
            let includedRecords = await this.app.service('propertyadds').find({
                query: {
                    property_id: pr.id
                }
            })
            pr.additionals = includedRecords.map(e => e.additional_id).sort();
            return pr;
        })
        return await Promise.all(newResData)
            .then(completed => {
                return {
                    total: oldRes.total,
                    limit: oldRes.limit,
                    skip: oldRes.skip,
                    data: completed
                }
            })
    }
}

可以看出,这是为扩展属性 class 创建一个 constructor 方法的问题,以便在 this.app 中公开 app 对象].这可以在调用 super(options,app) 使 this 可用后完成。

在此之后,只需使用 this.app 创建其他服务的实例,然后进行正确的异步调用即可。