Using Underscore Template with Knockout using interpolate due to asp.net

半城伤御伤魂 提交于 2019-11-29 12:20:12

Working Demo jsFiddle

HTML

<h1>People</h1>
<ul data-bind="template: { name: 'peopleList' }"></ul>

<script type="text/html" id="peopleList">
    {{ _.each(people(), function(person) { }}
        <li>
            <b data-bind="text: person.name"></b> is {{= person.age }} years old
        </li>
   {{ }) }}
</script>

<p>This shows that you can use both Underscore-style evaluation (<%= ... %>) <em>and</em> data-bind attributes in the same templates.</p>

JS

/* ---- Begin integration of Underscore template engine with Knockout. Could go in a separate file of course. ---- */
    ko.underscoreTemplateEngine = function () { }
    ko.underscoreTemplateEngine.prototype = ko.utils.extend(new ko.templateEngine(), {
        renderTemplateSource: function (templateSource, bindingContext, options) {
            // Precompile and cache the templates for efficiency
            var precompiled = templateSource['data']('precompiled');
            if (!precompiled) {
                _.templateSettings = {
                    interpolate: /\{\{=(.+?)\}\}/g,
                    escape:      /\{\{-(.+?)\}\}/g,
                    evaluate:    /\{\{(.+?)\}\}/g
                };

                precompiled = _.template("{{ with($data) { }} " + templateSource.text() + " {{ } }}");
                templateSource['data']('precompiled', precompiled);
            }
            // Run the template and parse its output into an array of DOM elements
            var renderedMarkup = precompiled(bindingContext).replace(/\s+/g, " ");
            return ko.utils.parseHtmlFragment(renderedMarkup);
        },
        createJavaScriptEvaluatorBlock: function(script) {
            return "{{= " + script + " }}";
        }
    });
    ko.setTemplateEngine(new ko.underscoreTemplateEngine());
/* ---- End integration of Underscore template engine with Knockout ---- */

var viewModel = {
    people: ko.observableArray([
        { name: 'Rod', age: 123 },
        { name: 'Jane', age: 125 },
    ])        
};

ko.applyBindings(viewModel);
Judah Gabriel Himango

You're asking how to change Underscore's delimiter characters? This SO answer seems to have the right answer. Basically, you can define your own regex for nesting data:

_.template("hello <?= name ?>", {"name": "Mike"}, {"interpolate": /<?=([\s\S]+?)%>/g) ?>})

A couple of side notes:

You say you're using Underscore, instead of Knockout's native template engine, for performance reasons. As an avid Knockout user, this sounds fishy. Knockout's native template engine is very fast and ultimately tested far more than 3rd party engines plugged into Knockout. I've built numerous applications with KO and never had an issue with the template engine being too slow. Make sure you really need to use Underscore. For the vast majority of cases, Knockout's native template engine works perfectly fine.

Secondly, are you aware of the Razor syntax? This wouldn't interfere with Underscore.

The _.templateSettings configuration is global, so just add the block

_.templateSettings = {
    interpolate : /\{\{(.+?)\}\}/g
};

anywhere earlier in your code.

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