Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在Express中将内容从模板传递到版面?_Javascript_Node.js_Pug - Fatal编程技术网

Javascript 如何在Express中将内容从模板传递到版面?

Javascript 如何在Express中将内容从模板传递到版面?,javascript,node.js,pug,Javascript,Node.js,Pug,我有一个基本的Express服务器: // server.js: var Express = require('express'); app = Express.createServer(); app.configure(function(){ app.set('views', Path.join(__dirname, 'views')); app.set('view engine', 'jade'); app.set('view options'); }); app.get('/'

我有一个基本的Express服务器:

// server.js:
var Express = require('express');
app = Express.createServer();
app.configure(function(){
  app.set('views', Path.join(__dirname, 'views'));
  app.set('view engine', 'jade');
  app.set('view options');
});
app.get('/', function (request, response) {
  response.render('welcome', {
    locals: {some: 'Locals'}
  });
});
具有基本的jade布局:

// views/layout.jade:
!!! 5
html(lang='en')
  head
    title= pageTitle
  body
    h1= pageTitle
    aside(id="sidebar")= sidebarContent
    #content
      #{body}
还有一个简单的页面:

# views/welcome.jade:
// How do I pass pageTitle and sidebarContent out to the layout from here?
p
  Welcome to my fine site!

(在Rails中,这可能类似于
content\u for
或一个简单的实例变量。)

以局部变量传递它:
{some:'locals',pageTitle:'Welcome!'}
Express在Rails中没有“blocks”或任何他们称之为“blocks”的预设概念,但您可以使用helpers()和dynamicchelpers()的组合取得类似的成就


通过使用上面关于DynamicPers的技巧和闭包的魔力,我发现了一个相当优雅的解决方案,它可以在不涉及请求对象的情况下工作。诀窍是将页面标题变量包装在一个闭包中,该闭包提供了一个get()和set()函数,并使该包装器对象成为页面标题动态助手的结果

创建property.js:

exports.create = function () {
    var value = null;
    return {
        get: function () {
           return value;
        },
        set: function (new_value) {
           value = new_value;
        }
    };
}
因此调用create()返回一个对象,该对象上有一个get()和set()方法,该方法获取并设置闭包变量

然后,在应用程序的设置代码中:

    var property = require("./property.js");
    app.dynamicHelpers ({
        page_title: function () {
         return property.create ();
        }
    });
由于动态助手的值是调用其函数的结果,因此在视图和模板中,page_title变量将是带有get()和set()函数的包装器对象

在你看来,你可以说:

- page_title.set ("my specific page title");
在您的布局中:

title= page_title.get()
要进一步简化此操作,请将其添加到property.js:

exports.creator = function () {
    return function () {
        return exports.create();
    };
}
用于将动态助手声明块简化为:

        var property = require("./property.js");
        app.dynamicHelpers ({
            page_title: property.creator()
        });

您可以使用这个小片段来实现这一点

道具js:

var hash = {};
module.exports = function() {
    return {
        set: function(key, val) { hash[key] = val },
        get: function(key) { return hash[key] }
    };
};
server.js:

app.dynamicHelpers({ prop: require(__dirname + '/views/helpers/prop') });

视图:


布局:

<%= prop.get('foo') %>

layout.jade

# the following function is a safe getter/setter for locals
- function pagevar(key, value) { var undef; return (value===undef) ? locals[key] || null : locals[key] = value; }
block config
  #intended as a non-rendered block so that locals can be overridden.
  # put your defaults here... - use append in the child view
!!!
html
  head
    title=pagevar('title')
    meta(name='description',content=pagevar('description'))
...
杰德

append config
  - locals.title = 'override';
  - locals.description = 'override 2';
  - pagevars('somekey', 'some value');
...

轻松peazy。

对于Express 3模板不可知论者,可以很好地处理
Express片段

app.use (req, res, next)->
  req.locals = {} unless req.locals

  res.locals.content_for = (k, v = null)->
    if !v
      req.locals[k]
    else
      req.locals[k] = v

  next()

我没有该模板中的
本地人
。我必须保留
{template path:page title}
的映射,并在呈现之前查找页面标题。必须有一种方法从模板本身中指定它。因此,我们的想法是添加一个动态帮助程序,在请求中存储
pageTitle
,然后布局可以读取它?这听起来是个很好的解决办法。我甚至可以把它包装成一个中间件并发布它!虽然它是基于DocPad的cms,但您可能会发现它很有用,因为它内置了对布局和jade的支持。闭包是我遇到的最实用的用法之一!你是如何在视图中实际使用它的?我喜欢这个想法,但对我来说,set()函数永远不会被调用,get()总是空的。
app.use (req, res, next)->
  req.locals = {} unless req.locals

  res.locals.content_for = (k, v = null)->
    if !v
      req.locals[k]
    else
      req.locals[k] = v

  next()