我已经使用nunjucks几个月了,并且发现它是一个很棒的模板引擎。然而,今天早上我遇到了一个看似简单的问题,但我根本想不出来。我希望另一组眼睛可以帮助指出解决方案。
问题:如果我将一个函数传递给一个模板,那么传递给该函数的任何参数都是在函数体内未定义的。
值和对象可以毫无问题地传递给模板,如果我传递一个函数,我可以从函数内部登录到控制台(所以我知道函数本身就在那里),但参数都是未定义的。 / p>
这最初似乎可以通过闭包来解决,但是1)我没有看到我能找到的任何示例中的闭包,以及2)当我尝试闭包时,我发现它们也接收到未定义的参数。
在一天的过程中,我把我的代码简化回到了最简单的案例中,仍然无法弄清楚这一点:
模板:
<div>
<p>{{ value }}</p>
<p>{{ object|pretty }}</p>
<p>{{ func(4) }}</p>
<p>{{ args(4)|pretty }}</p>
<p>{{ local(4) }}</p>
</div>
呈现模板的代码(这是在requirejs中定义的,未显示):
var nunjucks = require('lib/nunjucks-slim.min'), // v1.3.4
env = new nunjucks.Environment(null), // global templates
$tgt = $('#test'),
local;
env.addGlobal('value', 3);
env.addGlobal('object', {
a: 2
});
env.addFilter('pretty', function (obj) {
return JSON.stringify(obj, null, 2);
});
env.addGlobal('func', function (val) {
return 'func: ' + val;
});
env.addGlobal('args', function () {
return arguments;
});
local = function (val) {
return 'local: ' + val;
};
$tgt.html(env.render('test.nj', {
'local': local
}));
,呈现的HTML如下所示:
3 // value
{ "a": 2 } // object|pretty
func: undefined // func
{} // args
local: undefined // local
所以,一个值很好。该对象也可以工作,甚至在通过&#34;漂亮的&#34;之后看起来也很漂亮。过滤
然而,传递给&#34; func&#34;的值在函数体中变得未定义,并且在函数内使用arguments变量没有帮助。此外,将函数直接传递到模板上下文(本地)也不起作用。
过滤器(基本上只是函数)工作正常,但常规函数不会,无论它们是作为模板上下文的一部分传递还是作为全局函数传递。
可能会有所帮助的一些注意事项:
我正在使用requirejs(除了导入nunjucks本身)我试图从等式中消除它。
此示例使用nunjucks v1.3.4。在调试过程中,我试图在v2.1中验证这种行为,但似乎v2.x可能已经破坏了requirejs的兼容性,我不想并行解决两个问题。
我正在使用grunt-nunjucks预编译我的模板,然后对结果进行uglification。我的Gruntfile的相关部分如下:
module.exports = function (grunt) {
'use strict';
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
nunjucks: {
common: {
baseDir: 'site/',
src: [
'site/core/**/*.nj'
],
dest: 'application/static/js/common.js'
},
},
uglify: {
templates: {
options: {
preserveComments: false,
mangle: true,
compress: {
dead_code: true,
loops: true,
conditionals: true,
booleans: true,
unused: true,
if_return: true,
join_vars: true,
drop_console: true
}
},
files: {
'application/static/js/common.min.js': ['application/static/js/common.js'],
}
}
},
});
grunt.loadNpmTasks('grunt-nunjucks');
grunt.loadNpmTasks('grunt-contrib-uglify');
};
测试模板(如上所示)是编译成common.js的几个之一,然后使用上面的设置uglified到common.min.js。请注意,我已尝试编译模板而不进行uglifying,但得到相同的结果。
这是非常基本的功能所以如果这是一个错误,我希望在SE和问题日志中看到很多引用,但我几乎找不到。我想我错过了一些非常明显的东西,但似乎无法找到它。
有什么想法吗?
答案 0 :(得分:2)
继续调试之后,我最终采用uglification和requirejs进行了以下测试设置:
的index.html:
<html>
<head>
<script src="nunjucks-slim.js"></script>
<script src="common.js"></script>
</head>
<body>
<script src="test.js"></script>
</body>
</html>
我的模板,预编译为common.js:
<div>
<p>{{ value }}</p>
<p>{{ object|pretty }}</p>
<p>{{ func(4) }}</p>
<p>{{ func(x) }}</p>
<p>{{ args(4)|pretty }}</p>
<p>{{ local(4) }}</p>
<p>{{ local(x) }}</p>
</div>
test.js是练习模板的代码:
var env = new nunjucks.Environment(null),
local;
env.addGlobal('value', 3);
env.addGlobal('object', {
a: 2
});
env.addFilter('pretty', function (obj) {
return JSON.stringify(obj, null, 2);
});
env.addGlobal('func', function (val) {
return 'func: ' + val;
});
env.addGlobal('args', function () {
return arguments;
});
local = function (val) {
return 'local: ' + val;
};
console.log(env.render('core/root/test.nj', {
'local': local,
'x': 4
}));
最后,演示问题的输出(添加了注释):
<div>
<p>3</p> // value
<p>{
"a": 2 // object|pretty
}</p>
<p>func: undefined</p> // func(4)
<p>func: undefined</p> // func(x)
<p>{}</p> // args(4)|pretty
<p>local: undefined</p> // local(4)
<p>local: undefined</p> // local(x)
</div>
我花了几个小时逐步完成编译的模板代码,试图找到问题(顺便提一下,这是非常有用的信息),然后面对面 - 因为我已经消除了requirejs
我可以再试一次nunjucks v2.1.0
。
稍后点击几下,我就有了测试代码:
<div>
<p>3</p>
<p>{
a: 2
}</p>
<p>func: 4</p>
<p>func: 4</p>
<p>{
0: 4
}</p>
<p>local: 4</p>
<p>local: 4</p>
</div>
所以,虽然找出并解决问题会很好(使用v1.3.4),答案似乎是&#34;升级到nunjucks v2.1.0&#34;