0

我正在尝试升级网站以使用 jsRender 模板(它曾经使用 jTemplates)并且我一直在研究 jsRender(Boris 的网站和 John Papa 制作的材料)并尝试按照此处的说明进行操作:JSViewsRemoteLoadTemplates

请注意,截至 2013 年 11 月 13 日,此问题已被编辑以反映部分解决方案并清理内容:

经过大量实验后,我能够让 jsRender 模板处理静态数据,但是一旦我将数据更改为 ajax 源,模板就会呈现为空。我相信它可能会呈现为空,因为我没有在 .js 模板本身中指定正确的措辞,但我已经尝试了各种变体,但还没有任何效果。

我的页面是一个基本的.htm 页面。我在标题中使用 jQuery 1.10.2、json.js 和 jsrender.min.js。这是我在页面上的脚本:

<script style='text/javascript'>
$(function () {
    lazyGetTemplate('PopupChildren');
});

function lazyGetTemplate(name) {
    var deferred = $.Deferred();
    if ($.templates[name]) {
        deferred.resolve();
    }
    else {
        $.getScript("/_Scripts/" + name + ".js").then(function () {
            if ($.templates[name]) {
                deferred.resolve();
            }
            else {
                alert("Script: \"" + name + ".js\" failed to load.");
                deferred.reject();
            }
        });
    }
}

/* This is my sample static data that jsRender works with */
var staticdata = [
{
    "TypeID": "88", "Value": "ORGANICS"
},
{
    "TypeID": "89", "Value": "SPECIFIED ORGANICS"
}
];

function getMyTemplate(data) {
    $div_Child.html($.templates.PopupChildren.render(data)); 
 //change data to staticdata to test static info, I've also set this to JSON.stringify(data) but the result is still empty
}

/* This is the ajax that calls the external function I'm using for testing */
function selItem(cControl, treeID, treeTrans) {
    var parentID = treeID;

    if ($(cControl).parent().find('ul').length == 0) {
        $.ajax({
            type: "Post",
            url: "Contractor_ws.asmx/web_getChildren",
            async: true,
            dataType: "text",
            data: "{parentID:" + parentID + ", popupType:'" + $('#hid_popupType').val() + "'}",
            contentType: "application/json",
            success: function (data) {
                if (data != null) { //menu item has children
                    $(cControl).after("<div id=\"div_Child\"></div>");
                    $div_Child = $(cControl).parent().find('#div_Child');
                    $div_Child.hide();
                    getMyTemplate(data); 
                    $div_Child.show('slow');
                }
            },
            error: function (xhr) {
                alert(xhr.responseText);
            }
        });
    }
}

</script>

PopupChildren 脚本(模板):

$.templates("PopupChildren", "<ul>{{for}}<li><a onclick='selItem(this,'{{:TypeID}}','{{:Value}}');'>{{:Value}}</a></li>{{/for}}</ul>");

示例 ajax 数据:

数据:"{"d":[{"__type":"BLS","TreeCode":"0130","TreeType":"OBJ","ParentID":88,"Children":[],"TypeID" :89,"值":"无机酸,未指定","反式":"无机酸,未指定","Active_Flag":false},{"__type":"BLS","TreeCode":"0131"," TreeType":"OBJ","ParentID":88,"Children":[],"TypeID":90,"Value":"CHLORINE-CONTAINING OXYACIDS","Trans":"CHLORINE-CONTAINING OXYACIDS","Active_Flag “:错误的}]}”

4

2 回答 2

0

我找到了我遇到的问题的解决方案,它结合了我如何调用模板和在 ajax 中设置的参数。这是对我有用的解决方案:

$(function () { /* js ready function */
    lazyGetTemplate('PopupChildren');
});

/* this is the function that loads the template from the script */
function lazyGetTemplate(name) {
   var deferred = $.Deferred();
   if ($.templates[name]) {
       deferred.resolve();
   }
   else {
    $.getScript("/_Scripts/" + name + ".js").then(function () {
        if ($.templates[name]) {
            deferred.resolve();
        }
        else {
            alert("Script: \"" + name + ".js\" failed to load.");
            deferred.reject();
        }
    });
   }
 }

/* this is the ajax calling my additional items for display */
function selItem(cControl, treeID, treeTrans) {
var parentID = treeID;

if ($(cControl).parent().find('ul').length == 0) {
    $.ajax({
        type: "Post",
        url: "Contractor_ws.asmx/web_getChildren",
        async: true, 
        dataType: "JSON",
        data: "{parentID:" + parentID + ", popupType:'" + $('#hid_popupType').val() + "'}",
        contentType: "application/json",
        success: function (data) {
            if (data != null) { //menu item has children
                $(cControl).after("<div id=\"div_Child\"></div>");
                $div_Child = $(cControl).parent().find('#div_Child');
                $div_Child.hide();
                var myData = data.d;
                $div_Child.html($.templates.PopupChildren.render(myData));
                $div_Child.show('slow');
            }
        },
        error: function (xhr) {
            alert(xhr.responseText);
        }
    });
  }
}

/* this is the content of the actual script that gets called from the lazyGetTemplate() */
$.templates("PopupChildren", "<ul>{{for}}<li><a onclick=\"selItem(this,\'{{:TypeID}}\',\'{{:Value}}\');\">{{:Value}}</a>{{/for}}</ul>");

关于我在为 js/jsRender 新手实现这个特定的 jQuery 时学到的一些具体说明。在调用模板之前,我必须确保模板已加载到页面上。当我将数据传递给模板时,我还必须引用“data.d”。调用数据是不够的。当我对 ajax 数据感到困惑时,我还浪费了一些宝贵的时间,并认为我试图显示的项目位于一个名为 Children 的数组中,我发现事实并非如此。完成这项工作的最后两部分是我必须将 async 设置为 true,并且必须将 dataType 设置为“JSON”。特别是关于数据类型,还有另一篇文章提到将其设置为“文本”以使其工作,并且我的问题最终并不适用,但它可能会在未来帮助其他人。最后,特别是关于模板脚本本身,我不必在 for 语句中列出实际的项目名称。根据我看到的一些示例,我认为我需要放置 {{for data}} 或 {{for Children}} 但是,我假设,因为我最后通过了 data.d,只需调用 {{for} } 就足够了。

于 2013-11-15T14:29:41.573 回答
0

首先 - 您是否查看了JSViewsRemoteLoadTemplates页面上的“完整代码”选项卡?您可以运行该 HTML 页面作为测试和修改示例的起点

$.when()用于组合承诺。在你上面的例子中只有一个 - 所以你可以写(不使用$.when):

function getMyTemplate() {
    lazyGetTemplate("PopupChildren")
        .done(function () {
            var html = $.templates.PopupChildren.render(data);
            $div_Child.html(html);
         });
}

但是为了使您的模板正常工作,当前的语法是{{if ...}} {{/if}}和类似的 for {[for ...}}.

{{#if ...}} {{#/if}}是不正确的。(你还有一个额外的+:)'{{#/if}}' + );

在你的简化模板中,你应该写{{for Children}}- 我假设。{{for}}自己不会做任何事...

于 2013-11-13T01:50:00.523 回答