Я пытаюсь обновить веб-сайт, чтобы использовать шаблоны jsRender (он использовался для использования jTemplates), и я изучал jsRender (сайт Бориса и материал, созданный Джоном Папой), и пытался следовать инструкциям здесь: JSViewsRemoteLoadTemplates
Обратите внимание, что с 11/13/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:
data: "{" 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 " ":ложный}]}"
Я нашел решение проблемы, которую я имел, и это была комбинация того, как я вызывал шаблон и параметры, установленные в 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>");
Некоторые конкретные замечания о том, что я узнал при реализации этого конкретного jQuery для новичков js/jsRender. Я должен был убедиться, что шаблон загружается на страницу до ее вызова. Мне также пришлось ссылаться на "data.d", когда я передавал данные в шаблон. Вызов данных был недостаточным. Я также потратил немного драгоценного времени, когда меня смутили данные ajax и подумал, что элементы, которые я пытался отобразить, были внутри массива под названием "Дети", который я обнаружил не так. И последние две части, которые сделали эту работу, я должен был установить асинхронное значение true, и мне пришлось установить dataType в "JSON". В частности, о типе dataType есть еще одна публикация, в которой упоминается установка его "текста", чтобы он работал, и с моей проблемой, которая не зависела от нее, но ее чем-то, что могло бы помочь кому-то еще в будущем. И последнее, в частности, о самом скрипте шаблона, мне не нужно было указывать фактическое имя элемента в инструкции for. Я подумал, что, основываясь на некоторых примерах, которые я видел, мне нужно было поставить {{для данных}} или {{для детей}}, но, я предполагаю, потому что я передал data.d в конце, просто называя {{for} } было достаточно.
Сначала вы просмотрели вкладку "Полный код" на странице JSViewsRemoteLoadTemplates? Вы можете запустить эту страницу HTML в качестве отправной точки для тестирования и изменения выборки
$.when()
используется для объединения обещаний. В приведенном выше примере есть только один - так что вы можете писать (без использования $.when
):
function getMyTemplate() {
lazyGetTemplate("PopupChildren")
.done(function () {
var html = $.templates.PopupChildren.render(data);
$div_Child.html(html);
});
}
Но для того, чтобы ваш шаблон работал, текущий синтаксис {{if...}} {{/if}}
и аналогичным образом для {[for...}}
.
{{#if...}} {{#/if}}
неверен. (Также у вас есть дополнительный +
: '{{#/if}}' + );
)
И в вашем упрощенном шаблоне вы должны написать {{for Children}}
- я предполагаю. {{for}}
по себе ничего не сделает...