Javascript 使用ajax响应生成的handlebar.js模板

Javascript 使用ajax响应生成的handlebar.js模板,javascript,asp.net-mvc,handlebars.js,asp.net-ajax,jquery-select2,Javascript,Asp.net Mvc,Handlebars.js,Asp.net Ajax,Jquery Select2,模板在服务器端生成,并作为响应的一部分返回 "<div>{{name}}<small style='color:#999;'><br><code>{{vafm}}</code></small><br><code>{{email}}</code></div>" 不幸的是,上的渲染部分不包含数据返回的值。结果 我已将问题定位到此行 templateResult: Handle

模板在服务器端生成,并作为响应的一部分返回

"<div>{{name}}<small style='color:#999;'><br><code>{{vafm}}</code></small><br><code>{{email}}</code></div>"

不幸的是,上的渲染部分不包含
数据返回的值。结果

我已将问题定位到此行

templateResult: Handlebars.compile(t),
自从尝试了类似

<script>
    const template = Handlebars.compile(@Html.Raw(Model.Template));
</script>
一切正常

在上一个示例中,我从模型中传递模板


但我不需要从ajax响应中传递它并获得相同的输出。

存在多个问题:

  • templateResult
    需要一个回调函数,但您正在传递一个已编译的Handlebars模板对象。这在这里有描述。因此,假设您已经在正确的位置执行了以下操作:
那么,类似这样的方法就行了:

templateResult: function(data) {
    if (!data.id) return data.text;
    return $(t({
        name: 'example name',
        vafm: 'example vafm',
        email: 'example email'
    }));
$('#UniqueId').select2({
    ajax: {
        url: '/search/endpoint',
        dataType: 'json',
        processResults: function(data) {
            /** Note: select2 expects "results" to be an array of objects, each containing
             *  at least "id" (becomes the value) and "text" (displayed text). I made the
             *  format from the server match that (plus added some more info), so that I don't
             *  need any conversions except for compiling the template. I do that with
             *  Array.prototype.map() in this case, but of course a for-loop would work too.
             */
            return {
                results: data.map(function(e) {
                    e["template"] = Handlebars.compile(e["template"]);
                    return e;
                })
            };
        }
    },
    templateResult: function(el) {
        if (!el.id) return el.text;
        /*  Note: "el" will be just like it came from the server, except for the
         *  modifications we applied in processResults. We can just pass "el" to
         *  the compiled template entirely and there, only pick what we need.
         */
        return $(el["template"](el));
    }
});
  • 模板html必须有一个封闭元素,因此,例如,将内容放在

  • 您的模板缺少一个
    开始标记


因此,假设您的服务器发送一些JSON,如下所示。每个结果的模板都会一起发送,并且每个结果的模板都可能不同。模板特定的数据也是如此:

[
    {
        "id": 1,
        "text": "Henry",
        "data": {
            "vafm": "1234",
            "email": "henry@example.com"
        },
        "template": "<div>{{text}}<br><small>vafm: {{data.vafm}}</small></div><small>email: {{data.email}}</small>"
    }, {
        "id": 30, 
        "text": "Tesla Roadster",
        "data": {
            "price": "$200.000",
            "color": "dark red"
        },  
        "template": "<div>{{text}}<br><small>price: {{data.price}}</small></div><small>color: {{data.color}}</small>"
    }
]

你的帖子非常有用。不幸的是,我希望在服务器端创建模板,因为它将基于端点。硬编码与我想解释的内容脱节了。当然,我也相应地修改了答案。非常感谢。不幸的是,这也无济于事。json属性和模板因端点而异。我正在寻找一个通用的解决方案。我不希望通过使用templateResult:template来坚持硬编码属性,如电子邮件、vafm。我可以做到这一点,但我希望从ajax响应加载模板,而不是从模型本身加载模板。我不确定我是否理解。模板本身现在可以不同,具体取决于端点。您的意思是填写的信息(姓名、电子邮件、vafm)也应该不同,例如,对于不同的端点,可能是姓名、年龄、性别?如果这是你需要的,我可以改变我的答案是的,这是正确的。因此,我在服务器上生成json和相应的模板。终点可以是任何东西,搜索/用户、搜索/产品等等。通过这种方式,我可以获得用户名、EmailConfirm,或者在第二种情况下获得productName、productPrice,或者任何适合我需要的东西。我想从data.results生成一个keyvalue数组就可以了
templateResult: function(data) {
    if (!data.id) return data.text;
    return $(t({
        name: 'example name',
        vafm: 'example vafm',
        email: 'example email'
    }));
[
    {
        "id": 1,
        "text": "Henry",
        "data": {
            "vafm": "1234",
            "email": "henry@example.com"
        },
        "template": "<div>{{text}}<br><small>vafm: {{data.vafm}}</small></div><small>email: {{data.email}}</small>"
    }, {
        "id": 30, 
        "text": "Tesla Roadster",
        "data": {
            "price": "$200.000",
            "color": "dark red"
        },  
        "template": "<div>{{text}}<br><small>price: {{data.price}}</small></div><small>color: {{data.color}}</small>"
    }
]
$('#UniqueId').select2({
    ajax: {
        url: '/search/endpoint',
        dataType: 'json',
        processResults: function(data) {
            /** Note: select2 expects "results" to be an array of objects, each containing
             *  at least "id" (becomes the value) and "text" (displayed text). I made the
             *  format from the server match that (plus added some more info), so that I don't
             *  need any conversions except for compiling the template. I do that with
             *  Array.prototype.map() in this case, but of course a for-loop would work too.
             */
            return {
                results: data.map(function(e) {
                    e["template"] = Handlebars.compile(e["template"]);
                    return e;
                })
            };
        }
    },
    templateResult: function(el) {
        if (!el.id) return el.text;
        /*  Note: "el" will be just like it came from the server, except for the
         *  modifications we applied in processResults. We can just pass "el" to
         *  the compiled template entirely and there, only pick what we need.
         */
        return $(el["template"](el));
    }
});