【问题标题】:Request handler unable to render view with Vision plugin请求处理程序无法使用 Vision 插件呈现视图
【发布时间】:2019-04-10 06:29:06
【问题描述】:

我正在开发一个 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,代码似乎以正确的顺序运行,但还是失败了。

【问题讨论】:

    标签: javascript hapijs hapijs-vision


    【解决方案1】:

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

    确实:在插件中,server.getViewsManager()(由vision 装饰)在注册visionserver.views 后会显示一些内容,而您的路由中的相同调用(因此,在插件注册后)将显示@ 987654328@。 “参考”就这么多了。

    我刚刚尝试了与您类似的结构,得到了相同的错误,并且该线程向我指出了一种解决方法:注册您的 views 插件时,只需在选项中传递对“真实”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,
            });
        },
    };
    
    // test setup
    // ...
        const server = new Hapi.Server();
        // ...
        await server.register({
            plugin: require('../../server/views'),
            options: {
                path: path.join(__dirname, '../views/templates'),
                realServer: server // <= added option
            }
        });
    

    而且,显然,在您注册此插件的任何地方都有相同的选项。

    【讨论】:

    • 谢谢,这是有道理的。我注意到这也不起作用sinon.spy(server, "register")。当我查看源代码时,我想我记得看到服务器被克隆或其他东西。
    • 你在哪个版本中使用了这个代码块?我正在使用18.1.0 版本,当我尝试使用它时,realServer 参数未定义@Peter
    • 抱歉——我现在不记得了——那是不久前的事了,我已经显着改变了源代码@hardc0der :/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 2017-12-09
    • 2014-04-22
    • 1970-01-01
    • 2020-07-28
    • 2021-05-03
    • 2013-03-24
    相关资源
    最近更新 更多