How can I use the “locals” option in jade compile(), client-side?

浪子不回头ぞ 提交于 2019-12-13 04:46:58

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!