请求处理程序无法使用Vision插件呈现视图

时间:2019-03-25 07:37:34

标签: javascript hapijs hapijs-vision

我正在使用HapiJS api,并且定义了一个注册Vision插件并配置渲染引擎(ejs)的插件。但是当我尝试通过渲染视图来响应请求时,我得到了错误

  

AssertionError [ERR_ASSERTION]:缺少视图管理器

如果我在插件外的某个地方注册了Vision插件及其配置,则测试会通过,但我希望我应该能够将此逻辑封装在插件中。

// plugin
const ejs = require('ejs');
const Vision = require('vision');

module.exports = {
    name: 'views',
    version: '0.0.1',
    register: async (server, { path }) => {
        await server.register(Vision);
        server.views({
            engines: { ejs },
            path,
        });
    },
};

处理程序代码为

// api
server.route({
  path: '/korin/songs',
  method: 'GET',
  handler: async (request, h) => {
    try {
      const acceptType = getMediaType(request.headers.accept);
      const data = await server.methods.getTopTracks({
        getTopTracks,
        lastfmApi,
      });
      if (acceptType === 'text/html') {
        return h.view('index'); // <-- this errors
      }
      return data;
    } catch (error) {
      console.warn(error);
    }
  },
});

错误是由失败的测试生成的,

suite('render content', () => {
    test.only(`given text/html page should respond with header and footer`, async () => {
        const { server } = await setup();
        const { payload } = await server.inject({
            method: 'GET',
            url: '/korin/songs',
            headers: {
                accept: 'text/html',
            },
        });

        expect(payload).to.contain(`<header>`);
        expect(payload).to.contain(`<footer>`);
    });
});
// test setup
const setup = async options => {
    const server = new Hapi.Server();

    // truncated for brevity
    await server.register({
        plugin: require('../../server/api'),
        options: {
            ...defaults,
            ...options,
        },
    });

    await server.register({
        plugin: require('../../server/views'),
        options: { path: path.join(__dirname, '../views/templates') },
    });

    return {
        server
    };
};

有什么我想念的吗?我尝试运行console.log,并且代码似乎以正确的顺序运行,但无论如何还是失败。

1 个答案:

答案 0 :(得分:1)

有一个old thread on GitHub。 TL; DR:注册时传递给插件的对server的引用与“ root” server略有不同。关于领域的一些差异,显然仍然是一个问题。

确实:在插件中,server.getViewsManager()vision注册后的vision(由server.views装饰)将显示某些内容,而您的路线中有相同的呼叫(因此,在插件注册后)将显示null。 “参考”就这么多。

我刚刚尝试了一个与您类似的结构,但遇到了相同的错误,该线程向我指出了一种解决方法:注册views插件时,只需传递对“真实” {{1}的引用}。

server
// plugin
const ejs = require('ejs');
const Vision = require('vision');

module.exports = {
    name: 'views',
    version: '0.0.1',
    register: async (server, { path, realServer }) => { // <= added option
        await realServer.register(Vision); // <= replaced server w/ realServer
        realServer.views({ // <= replaced server w/ realServer
            engines: { ejs },
            path,
        });
    },
};

很明显,在注册此插件的任何地方都有相同的选项。