Передача массива объекту JSON для рендеринга Jade

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

Это код Джейда:

!!! 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. Оповещение во второй строке не срабатывает, потому что ошибка Unexpected Identifier возникает, как только я пытаюсь присвоить переменную #{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. Что бы я ни делал, я продолжаю получать ошибку «Неожиданный идентификатор». Кто-нибудь из вас знает, как мне это решить?

Спасибо


person Masiar    schedule 28.11.2011    source источник
comment
По какой причине у вас нет jade, перебирающего массив и создающего список как часть шаблона? Найдите итерацию по адресу github.com/visionmedia/jade.   -  person Ryan Olds    schedule 28.11.2011
comment
Ну, это другой взгляд на вещи. Я понял, что вы имеете в виду, но не могли бы вы привести пример того, что вы сказали в ответ на этот вопрос? Я хотел бы посмотреть, как бы вы это сделали, не сталкиваясь с ошибкой Неожиданный идентификатор. Спасибо   -  person Masiar    schedule 28.11.2011
comment
Можно попробовать {ranking: JSON.stringify(result)}. Чтобы было ясно, это не оптимально. Построение списка как части шаблона с использованием функциональности Jade «Итерация» полностью избавляет браузер от необходимости выполнять для этого JavaScript.   -  person Ryan Olds    schedule 28.11.2011
comment
Выполнение этого var rankArray = JSON.stringify(#{ranking}); снова дает непредвиденную ошибку идентификатора. То же самое происходит с var rankArray = {ranking: JSON.stringify(#{ranking})};. Я до сих пор не понимаю, как построение списка непосредственно в HTML позволит избежать ошибки JavaScript, которую я получаю, поскольку каждый раз, когда JS пытается оценить #{ranking}, он выдает ошибку.   -  person Masiar    schedule 28.11.2011
comment
Мое выше предложение должно быть помещено в маршрут, а не в шаблон.   -  person Ryan Olds    schedule 28.11.2011
comment
Ах, ладно, извините, что не понял этого. Упорядочивание результата приводит к следующему результату: ` var rankArray = {ranking:[{Username:...}]};` есть идеи, как избавиться от "вещей?   -  person Masiar    schedule 28.11.2011
comment
давайте продолжим это обсуждение в чате   -  person Masiar    schedule 28.11.2011


Ответы (4)


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

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

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

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

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

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

person luismreis    schedule 18.01.2012
comment
Прежде чем сделать это, убедитесь, что рейтинг не содержит неэкранированных строк, управляемых пользователем: escape.alf.nu /2 - person James; 17.02.2014
comment
действительно помогло ... большое спасибо, чувак. ваш ответ спас мою 1-дневную работу - person vijay kumar; 12.09.2014

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

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

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

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

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

var rankArray = JSON.parse( !{JSON.stringify(ranking)} );
person Matt Kneiser    schedule 20.03.2013

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

res.render('template', pArrayOfData);

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

script(type='text/javascript').
            var _histData = !{JSON.stringify(pArrayOfData)};
person Razvan    schedule 13.12.2014

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

Из моего кода:
Серверная часть:

Строковать массив JSON

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

Внешний интерфейс:

Снова Stringify с помощью !{}

    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();
person ng-hacker-319    schedule 26.01.2015