3

我正在尝试从用 C# 编写的类库中预编译 JsRender 模板,使用侏罗纪脚本引擎来执行 JsRender。

这是我的代码:

var engine = new Jurassic.ScriptEngine();
engine.Execute(JsRenderContents);    
var precompiledTemplate = engine.CallGlobalFunction<string>(String.Concat("$.templates(\"", template, "\");"));

我已经$.templates()这个页面中获取了 JavaScript 函数调用,它指出

$.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

看来我不是第一个面对这个问题的人。我已从本页上一篇文章中获得建议,并将我的代码更改为以下内容:

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 函数。

4

2 回答 2

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);
    }
};
于 2014-06-16T21:27:35.247 回答
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上添加此场景的更多文档/示例。

于 2014-05-30T17:54:27.690 回答