Как визуализировать шаблон с помощью Koa

Мои усилия заключаются в том, чтобы перепроектировать мое приложение с Express на Koa, чтобы роуты.js и controllers.js работали раньше. Я пытаюсь создать небольшой механизм для рендеринга шаблона в Koa. Цель состоит в том, чтобы применить рабочий код для других модулей, автоматически загружающих различные механизмы шаблонов через переменную рендеринга, вызывающую module.view_engine для каждого модуля.routes . Вы можете помочь?

+---modules
|   +---core
|   |   +---client
|   |   |   \---views
|   |   |           equipment.pug
|   |   |           error.pug
|   |   |           home.pug
|   |   |           
|   |   \---server
|   |       +---configs
|   |       |       core.config.json
|   |       |       core.koa.configs.js
|   |       |       
|   |       +---controllers
|   |       |       core.server.controllers.js
|   |       |       
|   |       +---models
|   |       |       assembly.server.model.js
|   |       |       ecms_equipment.server.model.js
|   |       |       ecms_location.server.model.js
|   |       |       ecms_main.server.model.js
|   |       |       index.js
|   |       |       
|   |       \---routes
|   |               core.server.routes.js
|   |               
|   +---assemblys
|   |   +---client
|   |   |   \---views
|   |   |           assembly_view.pug
|   |   |           
|   |   \---server
|   |       +---controllers
|   |       |       assemblys.server.controllers.js
|   |       |       
|   |       \---routes
|   |               assemblys.server.routes.js

Это моя структура каталогов. С парой Lodash в каждом цикле я могу получить view_path, route, view_engine для каждого модуля в core.koa.configs.js.

modules[module] = {
    view_path: view_path,
    routes: routes,
    view_engine: view_engine
  };

В том же файле, когда module все еще находится внутри цикла _.each, я вызываю

// regex to narrow the scope of code experimenting
if (module.re('assemblys')) {
    // === var render here? ===
    require(routes)(app);
  }

Это приведет приложение к файлу Assembly.server.routes.js, содержащему следующее:

var controller  = require('../controllers/projects.server.controllers');


module.exports = function(app){
  app.get('/task', controller.assembly)
};

Затем в сборке.server.controllers.js я пытаюсь предоставить функцию сборки, но она не работает — 404:

// load Sequelize models
var models = require( process.cwd() + '/modules/core/server/models');

exports.assembly = function *() {
  var that = this.body, views = require('co-views');
  var render = views('../../client/views/' , {
    map: {pug: 'jade'}
  });
  var Assembly = models.Assembly;

  Assembly.findAll().then(function (assemblys) {
    that = yield render('assembly_view' , {assemblys: assemblys});
  });
};

Раньше я помещал var render в core.configs, чтобы иметь возможность использовать view_path прямо там, но затем, когда я передал render в function *(), я получил ошибку и сбой приложения! Когда рендеринг был в core.configs, у меня был файл route.js, экспортирующий это:

module.exports = function(app, render){
      app.get('/task', controller.assembly(render));
    };

Некоторые примеры Koa говорят об использовании route в этом app.use(route.get('/assembly', function *() { });, и я видел, что некоторые другие примеры просто используют это

app.get('/task', controller.assembly(render)); // cnpmjs.org, koan stack...

Я предпочитаю последнее. Но у меня возникли проблемы с yield render и с тем, как загрузить приложение, параметры рендеринга в генератор function *(app,render), я попробовал это, но это тоже не работает. Ошибка в трассировке стека.

Идея состоит в том, чтобы иметь в core.koa.configs.js:

if (module.re('assemblys')) {
    var render = views(view_path , {
        map: view_engine
    });
    require(routes)(app, render);
}

затем экспорт маршрутов

module.exports = function(app, render){
  app.get('/task', controller.assembly(render))
};

и контроллер может отображать сборки:

exports.assembly = function *(render) {
  var that = this.body, views = require('co-views');
  var Assembly = models.Assembly;

  Assembly.findAll().then(function (assemblys) {
    that = yield render('assembly_view' , {assemblys: assemblys});
  });
};

Обновление: см. трассировки стека, см. koa branch_commit. Файлы -compiled.js.map были сгенерированы ES6-Babel


person Pristine Kallio    schedule 30.08.2016    source источник
comment
Есть ли у вас какая-либо информация из консоли о 404, которую вы получаете? Не удивлюсь, если он работает так, как ожидалось, но 404 исходит из вашего файла Pug.   -  person ash    schedule 30.08.2016
comment
Спасибо за ваш вклад. imgur.com/a/A79vG Обновление с трассировкой стека. Я использую сервис совместного просмотра, вам нужен мой package.json?   -  person Pristine Kallio    schedule 30.08.2016


Ответы (1)


Коа (в отличие от экспресса) не ждет, пока вы зададите тело ответа. Если ваша промежуточная функция закончилась, а тело ответа пусто, она выдаст ответ 404. Вот почему в koa вы должны избегать обратных вызовов или обещать их.

Вот как ваша промежуточная функция должна выглядеть в стиле koa:

exports.assembly = function *(render) {
    var that = this.body, views = require('co-views');
    var Assembly = models.Assembly;

    var assemblys = yield Assembly.findAll();
    that = yield render('assembly_view' , {assemblys: assemblys});
};
person Valera    schedule 20.09.2017