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

时间:2022-03-01 16:58:53

What I'm trying to achieve

Server is a Node.js application. I'd like to share code with the client as Jade template helpers (for functions) or globals (for objects/variables). New helpers and globals should be available in every client template. This question is NOT about adding helpers to Jade when jade is used server-side.

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

The code

I wrote a RequireJS wrapper for Jade compile() function, passing the locals object (filled with properties to share) inside options:

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

// ./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);
        }
    };
});

Problems and oddities

When I try to use moment it works fine:

当我尝试使用时刻它工作正常:

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

However, accessing the custom variable bar gives me no errors but an empty <p>:

但是,访问自定义变量栏不会给我带来任何错误,只有空

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

When I try to call the custom function foo() it gives me an error ("undefined is not a function"):

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

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

So, how am I supposed to use the locals options in the (client) Jade compile() function, for sharing code between the server and the client?

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

Updates

Update 1: as per @explunit comment, renaming the property moment into localmoment (inside options.locals), gives me an error undefined is not a function with the template p= localmoment().format(). I can't understand why...

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

Update 2: the solution proposed by @Isaac Suttell (expression function instead of anonymus one) doesn't work, I'm getting the same error with p= foo().

更新2:@Isaac Suttell提出的解决方案(表达式函数而不是anonymus one)不起作用,我在p = foo()时得到了同样的错误。

2 个解决方案

#1


3  

The call to moment().format() only works because moment is a global variable, so it's not being passed in at all into your template.

对moment()。format()的调用只能起作用,因为moment是一个全局变量,所以它根本不会传入你的模板。

The only way i know to get a function in to the template is trough the model it self. There might be better ways but i got this to work.

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

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)
              }
        }
    };
});

Then if you define your template like this

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

p #{bar}
p= foo() 

Everything should work nicely.

一切都应该很好地工作。

#2


0  

Try defining your function as expression function instead of an anonymous function:

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

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);
        };
    }
);

#1


3  

The call to moment().format() only works because moment is a global variable, so it's not being passed in at all into your template.

对moment()。format()的调用只能起作用,因为moment是一个全局变量,所以它根本不会传入你的模板。

The only way i know to get a function in to the template is trough the model it self. There might be better ways but i got this to work.

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

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)
              }
        }
    };
});

Then if you define your template like this

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

p #{bar}
p= foo() 

Everything should work nicely.

一切都应该很好地工作。

#2


0  

Try defining your function as expression function instead of an anonymous function:

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

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);
        };
    }
);