我试图用C#编写的类库预编译JsRender模板,使用Jurassic脚本引擎执行JsRender。
这是我的代码:
var engine = new Jurassic.ScriptEngine();
engine.Execute(JsRenderContents);
var precompiledTemplate = engine.CallGlobalFunction<string>(String.Concat("$.templates(\"", template, "\");"));
我已经从this page接受了JavaScript函数调用$.templates()
,该调用声明
$。templates(markupOrSelector)返回:编译的模板对象
我的示例HTML模板就是
<li>{{:Name}}</li>
但是,我的代码会产生异常:
'$.templates("<li>{{:Name}}</li>");' is not a function.
现在,我并不是100%清楚我是否可以在没有jQuery存在的情况下使用$运算符。作者在他的几个例子中包含了jQuery,但也指出jQuery不是必需的。
那么出了什么问题?在发布此问题的同一天,从GitHub获取的JsRender版本的文档是否过时了? (我知道JsRender还处于测试阶段。)或者我可能会误用侏罗纪?
修改
我认为这实际上是一个侏罗纪问题而不是JsRender问题。具体来说,我认为这与侏罗纪的全局对象有关,因为JsRender被包含在通过this
的立即调用函数中,并且我不确定侏罗纪提供this
。 / p>
看来我并不是第一个面对这个问题的人。我已经从this page的上一篇文章中获得了建议,并将我的代码更改为以下内容:
var engine = new Jurassic.ScriptEngine();
engine.Execute(JsRenderContents);
engine.Global["window"] = engine.Global;
var precompiledTemplate = engine.CallGlobalFunction<string>(String.Concat("window.jsviews.templates(\"", template, "\");"));
哪个不起作用 - 可能是因为JsRender的IIF仍然通过this
而不是window
,我不想修改脚本。
任何人都可以帮助推动这一进程吗?鉴于侏罗纪......我怎么能从侏罗纪打电话给任何 JsRender函数......我不知道......或许侏罗纪实现全球化的方式存在一些名义上的差异对象
答案 0 :(得分:1)
我使用jsRender + Jurassic预编译我的模板并在T4中生成js文件。 我花了很多时间来解决这个问题并没有找到答案,但阅读了一些有帮助的文章。
查看我的代码。它在我的案子里工作。我确定我可以帮助您解决问题,如果这样做无济于事:
var engine = new Jurassic.ScriptEngine();
var jsRenderPath = "/pathToDir/jsrender.js";
var jsUnevalPath = "/pathToDir/jsRenderUtils.js";
engine.ExecuteFile(jsRenderPath);
engine.ExecuteFile(jsUnevalPath);
engine.Evaluate("function renderTemplate(name, markup) { var tmpl = this.jsviews.templates(name, markup); return uneval(tmpl); }");
var compiledTemplateString = engine.CallGlobalFunction<string>("renderTemplate", templateName, templateString);
var result = "$.templates['" + templateName + "'] = " + compiledTemplateString + ";";
jsRenderUtils.js内容(uneval功能)
function uneval(obj, known) {
var root = (known === undefined), result;
known = known || [];
// some values fail eval() if not wrapped in a ( ) parenthesises
var wrapRoot = function (result) {
return root ? ("(" + result + ")") : result;
};
// special objects
if (obj === null)
return "null";
if (obj === undefined)
return "undefined";
if (obj !== obj) // isNaN does type coercion, so can't use that.
return "NaN";
if (obj === Infinity)
return "Infinity";
if (obj === -Infinity)
return "-Infinity";
// atoms
switch (typeof obj) {
case 'function':
return wrapRoot(obj.toString());
case 'number':
case 'boolean':
return obj.toString();
case 'string':
return "\"" + obj.toString() + "\"";
}
// circular reference check for non-atoms
if (known.indexOf(obj) !== -1)
return "null";//throw new Error("Circular references detected while unevaling.");
known.push(obj);
// specialized types
if (obj instanceof Array)
return "[" + obj.map(function (o) { return uneval(o, known); }).join(",") + "]";
if (obj instanceof Date)
return wrapRoot("new Date('" + obj.toString() + "')");
// hashes
var key, pairs = [];
for (key in obj) {
var val;
switch (key) {
case "render":
val = "$.fn.render";
break;
case "markup":
val = "null";
break;
default:
val = uneval(obj[key], known);
}
pairs.push("\r\n" + key + " : " + val);
}
return wrapRoot("{" + pairs.join(",") + "}");
};
更新:如果你将在没有jquery的情况下渲染模板,你应该添加:
$ = window.jsviews;
$.fn = {
render: function (data, view, j, u) {
return this.fn(data, view, j, u);
}
};
答案 1 :(得分:0)
JsRender可以在没有jQuery的情况下使用。
它的工作方式是对于像var compiledTemplate = $.templates(...);
这样的调用,如果没有加载jQuery,那么你应该设置$ = window.jsviews
(或等效,例如this.jsviews,在服务器上)。
所以你真的在呼唤:
compiledTemplate = this.jsviews.templates(...);
此处有一个示例:http://borismoore.github.io/jsrender/demos/step-by-step/20_without-jquery.html(此处代码为https://github.com/BorisMoore/jsrender/blob/master/demos/step-by-step/20_without-jquery.html)。
此处还有很多单元测试:http://borismoore.github.io/jsrender/test/unit-tests-jsrender-no-jquery.html(代码:https://github.com/BorisMoore/jsrender/blob/master/test/unit-tests-jsrender-no-jquery.html)。
稍后将在http://www.jsviews.com上添加此方案的更多文档/示例。