Передача массива в объект JSON для рендеринга Jade - PullRequest
15 голосов
/ 28 ноября 2011

У меня есть сервер node.js, написанный на express, и в определенный момент я отправляю на какую-то страницу .jade массив. Проблема в том, что при рендеринге страницы Jade компилятор Jade отображает массив как [object Object], а компилятор JavaScript в Chrome жалуется на это, говоря «Неожиданный идентификатор».

Это код Jade:

!!! 5
html(lang="en")
    head
    title= "Rankings"

    body
        h1 Ranking

        div(id="rankings")

    script(type='text/javascript')

        function fillRanking(){
            var rankArray = #{ranking};
            alert("inside fillranking");
            var divElement = document.getElementById("rankings");
            for(var i = 0; i< rankArray.length; i++){
                divElements.innerHTML += "" + i+1 + ". " + rankArray[i].Username + " " + rankArray[i].Points;
            }
        }

        fillRanking();

Как вы видите, это действительно просто, я просто заполняю div информацией, полученной из переменной #{ranking}, переданной node.js в Jade. Предупреждение во второй строке не срабатывает, потому что ошибка неожиданного идентификатора происходит, как только я пытаюсь присвоить переменную #{ranking}.

Ниже приведен код в моем файле node.js с выражением

app.get('/ranking', function (req, res) {
    //get the first ten people in the ranking
    var firstTen = getRanking(10, function(results){
        //compute the array of results
        var result = {
            ranking: [],
        }
        for(var i = 0; i < results.length; i++){
            result.ranking[i] = results[i];
        }
        //render the ranking with all the info
        console.log(result);
        res.render(__dirname + '/pages/ranking/ranking.jade', {
            ranking: result,
        });
    });
});

Я создаю объект с массивом результатов, помещаю результаты поиска в запрос и передаю его в механизм рендеринга. Вызов console.log(results) правильно печатает объект result, например, так:

{ ranking: 
   [ { Username: 'usr1',
       _id: 4ed27319c1d767f70e000002,
       Points: 100 },
     { Username: 'usr2',
       _id: 4ed27326c1d767f70e000003,
       Points: 100 } ] 
}

Я действительно не знаю, как обращаться с переменной, передаваемой на страницу Jade. Что бы я ни делал, я получаю ошибку «Неожиданный идентификатор». Кто-нибудь из вас знает, как мне решить эту проблему?

Спасибо

Ответы [ 4 ]

31 голосов
/ 18 января 2012

Глядя на комментарии выше и исследуя немного больше, вот что я нашел для работы:

Используйте это на своем javascript (/ controller):

...
res.render(__dirname + '/pages/ranking/ranking.jade', {
    ranking: JSON.stringify(ranking),
})
...

И по нефритовому шаблону:

...
function fillRanking(){
  var rankArray = !{ranking};
  alert("inside fillranking");
...

Это работает, потому что! {} Не выполняет экранирование.

10 голосов
/ 20 марта 2013

Это работает для меня.

JSON.stringify массив (или любой произвольный объект JSON на самом деле) на сервере, а затем JSON.parse на клиенте.

на стороне сервера:

res.render(__dirname + '/pages/ranking/ranking.jade', {
    ranking: JSON.stringify(result),
});

на стороне клиента:

var rankArray = JSON.parse( !{JSON.stringify(ranking)} );
3 голосов
/ 13 декабря 2014

Поскольку я также использую массив контроллера для итерации, я сделал это:

res.render('template', pArrayOfData);

А в нефритовом коде:

script(type='text/javascript').
            var _histData = !{JSON.stringify(pArrayOfData)};
0 голосов
/ 26 января 2015

Я столкнулся с той же проблемой и смог заставить ее работать с небольшими изменениями (благодаря решениям выше).

Из моего кода:
Backend:

Stringify массив JSON

router.get('/', function(req, res) {
    var data = JSON.stringify(apiData);  // <====
    res.render('gallery', { data: apiData });
}); 

Frontend:

Стринификация снова с! {}

    function injectDataOnView() {

        var data = !{JSON.stringify(data)}; // <====
        var divElement = document.getElementById('data');
        divElement.innerHTML = data[1]['id']; // <=== just a test, so no for loop
    }

    injectDataOnView();
...