Node.js Express - Как res.render () создает HTML с данными, когда эти данные не передаются ему? - PullRequest
0 голосов
/ 28 апреля 2018

Я использую Получение MEAN с Mongo, Express, Angular и Node от Саймона Холмса и в главе 7.2.3 Использование данных ответа API В разделе есть некоторые очень странное поведение. Кажется, что html генерируется из res.render () с данными, которые на самом деле не передаются ему. Когда передаются правильные данные, возникают разные ошибки в зависимости от того, как обрабатывается файл Jade. Ниже приведены файлы location.js , index.js и location-list.jade , включая вывод терминала, показывающий ожидаемый JSON. Все файлы находятся в папке app_server , видимой здесь https://imgur.com/a/Lfaj828

Для тех, кто не следует за книгой, этот вопрос относится только к вызываемому module.exports.homelist = function(req, res) {...}, это происходит, когда в браузере есть запрос на localhost: 3000 / . Все остальные запросы, такие как localhost: 3000 / location , ведут себя как ожидалось. Ключевыми данными, упомянутыми в предыдущем абзаце, является ответ на запрос API, называемый body внутри объекта request . Функция res.render () использует эти данные для местоположений и называется responseBody .

Существует несколько опций, в которых код закомментирован или не закомментирован, что приводит к различным выводам, как показано ниже. Это происходит в файле location.js в функциях renderHompage и module.exports.homelist , за исключением четвертого варианта. Ниже приведены варианты

  1. Удаление locations: responseBody из var renderHomepage = function(req, res, responseBody) {...} приводит к следующему html, показанному на этом изображении https://imgur.com/a/KduEdDG
  2. Включая locations: responseBody для var renderHomepage = function(req, res, responseBody) {...} создает следующий html-код, показанный на этом изображении https://imgur.com/a/Ck4FpFl
  3. Использование var renderHomepage = function(req, res) {...} приводит к тому же выводу, что и первая опция.
  4. Удаление строк 24 - 26 (все, что связано с объектами - см. Сообщение об ошибке из второго варианта) из location-list.jade и использование второго варианта, где включен responseBody, приводит к https://imgur.com/a/bYM8mVj и этот список пустых мест больше сотни, поэтому его можно прокручивать довольно долго.


Вывод на терминал, когда когда-либо localhost: 3000 запрашивается из браузера, используя Варианты Один, Три и Четыре. Второй вариант аналогичен, за исключением GET / 500 806.003 ms - 3396 в правильном месте.

GET /api/locations?lng=-122.236353&lat=37.485217 200 19.818 ms - 297
[{"distance":285.97478710956176,"name":"Peet's Coffee","rating":0,"facilities":["hot drinks"," food"," classical music"],"_id":"5ae25bd42d69c6abe46ae307"},{"distance":700.0951415645783,"name":"Philz Coffee","rating":4,"facilities":["hot drinks"," food"," power"],"_id":"5ae25c472d69c6abe46ae30a"}]
GET / 304 128.077 ms - -
GET /bootstrap/css/amelia.bootstrap.css 304 3.148 ms - -
GET /stylesheets/style.css 304 4.557 ms - -
GET /javascripts/jquery-1.12.4.min.js 304 8.150 ms - -
GET /bootstrap/js/bootstrap.min.js 304 6.275 ms - -
GET /bootstrap/fonts/glyphicons-halflings-regular.woff 304 0.551 ms - -

locations.js

var request = require('request');
var apiOptions = {
  server : "http://localhost:3000"
};
if (process.env.NODE_ENV === 'production'){
  apiOptions.server = "https://example.herokuapp.com/"; // not actual location
}

// var renderHomepage = function(req, res) { // uncomment for Option Three
//   res.render('locations-list', {
//     title: 'Loc8r - find a place to work with wifi',
//     pageHeader: {
//       title: 'Loc8r',
//       strapline: 'Find places to work with wifi near you!'
//     },
//     sidebar: "Looking for wifi and a seat? Loc8r helps you find places to work when out and about.  Perhaps with coffee, cake or a pint? Let Loc8r help you find the place you're looking for.",
//   });
// };

var renderHomepage = function(req, res, responseBody) { // comment out for Option Three
  res.render('locations-list', {
    title: 'Loc8r - find a place to work with wifi',
    pageHeader: {
      title: 'Loc8r',
      strapline: 'Find places to work with wifi near you!'
    },
    sidebar: "Looking for wifi and a seat? Loc8r helps you find places to work when out and about.  Perhaps with coffee, cake or a pint? Let Loc8r help you find the place you're looking for.",
    // locations: responseBody // comment out for Option One, uncomment out for Option Two
  });
};

/* GET 'home' page */
module.exports.homelist = function(req, res) {
  var requestOptions, path;
  path = '/api/locations';
  requestOptions = {
    url: apiOptions.server + path,
    method : "GET",
    JSON : {},
    qs : {
      lng : -122.236353,
      lat : 37.485217
    }
  };
  request(
    requestOptions,
    function(err, response, body){
      console.log(body);
      // renderHomepage(req, res);  // use for Option Three
      renderHomepage(req, res, body); // use for Option One and Two
    }
  );
};

/* GET 'Location info' page */
module.exports.locationInfo = function(req, res) {
    res.render('location-info', {
    title: 'Location info',
    name: 'Starcups',
    address: '125 High Street, Reading, RG6 1PS',
    rating: 5,
    facilities: ['Hot drinks', 'Premium wifi'],
    distance: '109m',
    description: " Simon's cafe is on Loc8r because it has accessible wifi and space to sit down with your laptop and get some work dont.",
    times: [
      "Monday - Friday : 7:00am - 7:00pm",
      "Saturday : 8:00am - 5:00pm",
      "Sunday : closed"
    ],
    reviews: [{
      name: "Simon Holmes",
      description: "What a great place. I can't say enough good things about it.",
      timestamp: "16 Febuary 2014",
      rating: 3
    },{
      name: "Judy Holmes",
      description: "It was okay. Coffee wasn't great, but the wifi was fast.",
      timestamp: "26 January 2015",
      rating: 3
    },{
      name: "Simon Cramp",
      description: "It was okay. Coffee wasn't great, but the wifi was fast.",
      timestamp: "6 September 2012",
      rating: 3
    },{
      name: "Simoolmes",
      description: "What a great place. I can't say enough good things about it.",
      timestamp: "14 June 2013",
      rating: 3
    }]
  });
};

/* GET 'Add review' page */
module.exports.addReview = function(req, res) {
    res.render('location-review-form', {
    title: 'Add review',
    name: 'Starcups' 
  });
}; 

Места-list.jade

extends layout

include _includes/sharedHTMLfunctions.jade

block content
  #banner.page-header
    .row
      .col-lg-6
        h1= pageHeader.title
          small  #{pageHeader.strapline}
  .row
    .col-xs-12.col-sm-8
      .error= message
      .row.list-group
        each location in locations
          .col-xs-12.list-group-item
            h4
              a(href="/location/#{location._id}")= location.name
              small  
                +outputRating(location.rating)
              span.badge.pull-right.badge-default= location.distance
            p.address= location.address
            p
              each facility in location.facilities
                span.label.label-warning= facility
                |                
    .col-xs.12.col-sm-4
      p.lead= sidebar

index.js

var express = require('express');
var router = express.Router();
var ctrlLocations = require('../controllers/locations');
var ctrlOthers = require('../controllers/others');

/* Location pages */
router.get('/', ctrlLocations.homelist);
router.get('/location', ctrlLocations.locationInfo);
router.get('/location/review/new', ctrlLocations.addReview);

/* Other pages */
router.get('/about', ctrlOthers.about);

module.exports = router;

Так что большой вопрос в том, как html отображает местоположения, которые не передаются в res.render (), как это видно в первом и третьем вариантах? Варианты 1 и 3, очевидно, очень похожи, но мне просто пришлось перепроверить, потому что это кажется странным. Я подумал, что возможно, что данные где-то кэшируются, поэтому я изменил значения широты и долготы в requestOptions, который показывает html, это изменение для Варианта Один и Три

Здесь не показано. Я заменил responseBody жестко закодированными данными о местоположении, приведенными ранее в книге, аналогично тому, что видно в module.exports.locationInfo = function(req, res) {...}, и все выглядело хорошо.

...