问题
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.
The code
I wrote a RequireJS wrapper for Jade compile()
function, passing the locals
object (filled with properties to share) inside 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);
}
};
});
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"):
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?
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...
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()
.
回答1:
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.
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:
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);
};
}
);
来源:https://stackoverflow.com/questions/17428984/how-can-i-use-the-locals-option-in-jade-compile-client-side