0

我想要达到的目标

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

编码

我为 Jade 函数编写了一个 RequireJS 包装器compile(),将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()时,它给了我一个错误(“未定义不是函数”):

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

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

更新

更新 1:根据@explunit 评论,将属性重命名momentlocalmoment(inside options.locals),给我一个错误undefined is not a function with the template p= localmoment().format()。我不明白为什么...

更新 2:@Isaac Suttell 提出的解决方案(表达式函数而不是匿名函数)不起作用,我在p= foo().

4

2 回答 2

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() 

一切都应该运行良好。

于 2013-07-10T10:15:20.340 回答
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);
        };
    }
);
于 2013-07-10T09:09:13.343 回答