Как передать переменную из файла шаблона jade в файл скрипта?



у меня возникли проблемы с переменной (config), объявленной в файле шаблона jade (index.jade), который не передается в файл javascript, что затем приводит к сбою моего javascript. Вот файл (представления / индекс.Джейд):



h1 #{title}

script(src='./socket.io/socket.io.js')
script(type='text/javascript')
var config = {};
config.address = '#{address}';
config.port = '#{port}';
script(src='./javascripts/app.js')


вот часть моего приложения.js (на стороне сервера):



  app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
app.set('address', 'localhost');
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
app.use(express.errorHandler());
});

// Routes

app.get('/', function(req, res){
res.render('index', {
address: app.settings.address,
port: app.settings.port
});
});

if (!module.parent) {
app.listen(app.settings.port);
console.log("Server listening on port %d",
app.settings.port);
}

// Start my Socket.io app and pass in the socket
require('./socketapp').start(io.listen(app));


и вот часть моего файла javascript, который аварийно завершает работу (public / javascripts / app.js):



(function() {
var socket = new io.Socket(config.address, {port: config.port, rememberTransport: false});


я запускаю сайт в режиме разработки (NODE_ENV=development) на локальный (моя собственная машина). Я использую node-inspector для отладки, который сказал мне, что переменная config не определена в public/javascripts/app.js.



какие идеи?? Спасибо!!

950   6  

6 ответов:

Это мало поздно, но...

script.
  loginName="#{login}";

это прекрасно работает в моем скрипте. В Express, я делаю это:

exports.index = function(req, res){
  res.render( 'index',  { layout:false, login: req.session.login } );
};

Я думаю, что последний нефрит отличается?

Merc.

правка: добавил "."после сценария, чтобы предотвратить предупреждение Джейд.

!{} на unescaped code интерполяция, которая больше подходит для объекты

script var data = !{JSON.stringify(data).replace(/<\//g, '<\/')}

{ foo: 'bar' }
// becomes:
<script>var data = {"foo":"bar"}</script>

{ foo: 'bar</script><script>alert("xss")//' }
// becomes:
<script>var data = {"foo":"bar<\/script><script>alert(\"xss\")//"}</script>

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

  1. вырваться из переменной: JSON.stringify экранирует кавычки
  2. выход из тега сценария: если содержимое переменной (которое вы не можете контролировать, если оно поступает из базы данных для ex.) имеет </script> строку, заменить заявление будет заботиться о нем

https://github.com/pugjs/pug/blob/355d3dae/examples/dynamicscript.pug


#{} для сбежавших строку интерполяции, которая подходит только если вы работаете со строками. Это не работает С объектом

script var data = #{JSON.stringify(data)}

//=> <script>var data = {&quot;foo&quot;:&quot;bar&quot;}</script>

в моем случае я пытался передать объект в шаблон через экспресс-маршрут (сродни настройке OPs). Затем я хотел передать этот объект в функцию, которую я вызывал через тег скрипта в шаблоне pug. Хотя lagginreflex это приблизил меня, я закончил со следующим:

script.
    var data = JSON.parse('!{JSON.stringify(routeObj)}');
    funcName(data)

это гарантировало, что объект был передан, как ожидалось, вместо того, чтобы десериализовать в функции. Кроме того, другие ответы, похоже, отлично работают с примитивами, но когда массивы и т. д. были переданы вместе с объектом они были проанализированы как строковые значения.

см. Этот вопрос: JADE + EXPRESS: итерация по объекту во встроенном JS-коде (на стороне клиента)?

У меня такая же проблема. Jade не передает локальные переменные в сценарии javascript (или вообще не делает никаких шаблонов), он просто передает весь блок в виде буквального текста. Если вы используете локальные переменные "адрес" и "порт" в вашем файле Jade над тегом сценария, они должны отображаться.

возможные решения перечислены в вопросе я связан выше, но вы можете либо: - передайте каждую строку в виде неоткрытого текста (!= в начале каждой строки), и просто поставить "-" перед каждой строкой JavaScript, который использует локальную переменную, или: - Передача переменных через элемент dom и доступ через JQuery (ugly)

нет ли лучшего способа? Похоже, создатели Jade не хотят поддержки многострочного javascript, как показано в этой теме в GitHub:https://github.com/visionmedia/jade/pull/405

если вы похожи на меня, и вы используете этот метод передачи переменных много, вот решение без записи кода.

в свой узел.JS route, передайте переменные в объект с именем window, например:

router.get('/', function (req, res, next) {
    res.render('index', {
        window: {
            instance: instance
        }
    });
});

затем в вашем файле макета pug/jade (непосредственно перед block content), вы получите их так:

if window
    each object, key in window
        script.
            window.!{key} = !{JSON.stringify(object)};

как мой макет.файл pug загружается с каждым файлом pug, мне не нужно "импортировать" мои переменные снова и снова.

таким образом, все переменные / объекты, переданные в window 'волшебно' в конечном итоге в реальном window объект Вашего браузера, где вы можете использовать их в Reactjs, Angular,... или ванильный javascript.

вот как я обратился к этому (используя среднюю производную)

мои переменные:

{
  NODE_ENV : development,
  ...
  ui_varables {
     var1: one,
     var2: two
  }
}

сначала я должен был убедиться, что необходимые конфигурационные переменные передаются. MEAN использует пакет node nconf и по умолчанию настроен на ограничение того, какие переменные передаются из среды. Я должен был исправить это:

config / config.js:

оригинал:

nconf.argv()
  .env(['PORT', 'NODE_ENV', 'FORCE_DB_SYNC'] ) // Load only these environment variables
  .defaults({
  store: {
    NODE_ENV: 'development'
  }
});

после модификации:

nconf.argv()
  .env('__') // Load ALL environment variables
  // double-underscore replaces : as a way to denote hierarchy
  .defaults({
  store: {
    NODE_ENV: 'development'
  }
});

теперь я могу установить мои переменные следующим образом:

export ui_varables__var1=first-value
export ui_varables__var2=second-value

Примечание: я сбросил "индикатор heirarchy" на "_ _ "(двойное подчеркивание), потому что его значение по умолчанию было":", что затрудняет установку переменных из bash. См. Еще один пост в этой теме.

теперь Нефритовая часть: Затем значения должны быть визуализированы, чтобы javascript мог забрать их на стороне клиента. Простой способ записать эти значения в файл индекса. Потому что это это одностраничное приложение (angular), эта страница всегда загружается первой. Я думаю, что в идеале это должен быть файл включения javascript (просто чтобы держать вещи в чистоте), но это хорошо для демонстрации.

приложение/контроллеры/индекс.js:

'use strict';
var config = require('../../config/config');

exports.render = function(req, res) {
  res.render('index', {
    user: req.user ? JSON.stringify(req.user) : "null",
    //new lines follow:
    config_defaults : {
       ui_defaults: JSON.stringify(config.configwriter_ui).replace(/<\//g, '<\/')  //NOTE: the replace is xss prevention
    }
  });
};

приложения/вид индекса/.Джейд:

extends layouts/default

block content
  section(ui-view)
    script(type="text/javascript").
    window.user = !{user};
    //new line here
    defaults = !{config_defaults.ui_defaults};

в моем визуализированном html, это дает мне хороший маленький скрипт:

<script type="text/javascript">
 window.user = null;         
 defaults = {"var1":"first-value","var2:"second-value"};
</script>        

С этого момента угловой легко использовать код.

Comments

    Ничего не найдено.