如何在jade compile(),客户端使用“locals”选项?

时间:2013-07-02 15:00:28

标签: javascript node.js browser requirejs pug

我想要实现的目标

Server是Node.js应用程序。我想与客户端共享代码作为Jade模板助手(用于函数)或全局用语(用于对象/变量)。每个客户端模板都应该有新的帮助器和全局变量。这个问题不是关于在服务器端使用jade时向Jade添加帮助程序。

代码

我为Jade compile()函数编写了一个RequireJS包装器,在locals内传递options对象(填充了要共享的属性):

// ./wrappers/jade.js
define(['jade', 'moment', 'lodash'], function (Jade, moment, _) {
    return {
        compile: function (str, options) {
            options.locals = _.extend({
                moment: moment,                    // moment function
                bar: 'foo',                        // Custom bar variable
                foo: function () { return 'bar'; } // Custom foo function
            }, options.locals);

            return Jade.compile(str, options);
        }
    };
});

问题和奇怪

当我尝试使用moment 时,它可以正常使用

p!= moment().format() //- Works: <p>2013-07-10T13:57:12+02:00</p>

但是,访问自定义变量bar会让我没有错误,只有空<p>

p #{bar} //- No errors but: <p></p>

当我尝试调用自定义函数foo()时,会给我一个错误(“ undefined不是函数”):

p= foo() //- Uncaught TypeError: undefined is not a function

那么,我应该如何使用(客户端)Jade compile()函数中的locals选项来共享服务器和客户端之间的代码?

更新

更新1 :根据@explunit评论,将属性moment重命名为localmoment(在options.locals内),给我一个错误 undefined不是带有模板p= localmoment().format()的函数。我不明白为什么......

更新2 :@Isaac Suttell提出的解决方案(表达式函数而不是匿名函数)不起作用,我与p= foo()收到同样的错误。

2 个答案:

答案 0 :(得分:3)

moment().format()的调用仅有效,因为moment是一个全局变量,因此它根本不会传入您的模板。

我知道将函数输入模板的唯一方法就是通过自己的模型。 可能有更好的方法,但我让它工作。

define(['jade', 'moment', 'lodash'], function (Jade, moment, _) {
    return {
        compile: function (str, options) {
              var compileFunction = Jade.compile(str, options);
              return function(){
                  // augment the model with the functions/vars you need
                  arguments[0] = _.extend(arguments[0] || {}, {
                    foo: function() { return "bar"; },
                    bar: "foo"
                  });
                  return compileFunction.apply(null, arguments)
              }
        }
    };
});

然后,如果您像这样定义模板

p #{bar}
p= foo() 

一切都应该很好用。

答案 1 :(得分:0)

尝试将函数定义为表达式函数而不是匿名函数:

define(['jade', 'moment'], function (Jade, moment) {
    return {
        compile: function (str, options) {
            var bar = function () { return 'bar'; }; // Function defined here instead
            options.locals = _.extend({
                'moment': moment,
                'foo': bar
            }, options.locals);

            return Jade.compile(str, options);
        };
    }
);