Пожалуйста, потерпите меня, поскольку я пытаюсь объяснить это, поскольку это несколько сложно, и я совершенно новичок в JQuery и пытаюсь обдумать это.
Моя команда и я работаем над WebParts для проекта SharePoint. Веб-часть содержит пользовательский элемент управления (SearchControl), который имеет ссылку для открытия диалогового окна (с помощью jquery ui), содержащего другой пользовательский элемент управления (SelectorControl).
SelectorControl содержит:
- раскрывающийся список (objTemplates), который заполняется с помощью шаблонов JQuery
- таблица, которая заполняется с помощью другого шаблона JQuery; и
- текстовый ввод только для чтения, чтобы отобразить текущий выбранный элемент из таблицы
Код выбора селектора:
<div class="objSelector">
<script id="objSelectorTemplate" type="text/x-jquery-tmpl">
<div class="table">
<div class="row">
<div class="labelInputGroup">
<label for="objTemplates">Obj Template</label>
<select id="objTemplates">
{{each ObjectTemplates}}
<option value="${ObjectTemplateId}">${Name}</option>
{{/each}}
</select>
</div>
</div>
<div><br></div>
<div class="row">
<div>
<table class="tableGrid">
<thead>
<tr>
<th>Object Name</th>
</tr>
</thead>
<tbody id="listPlaceholder">
</tbody>
</table>
<div id="pagerPlaceholder"></div>
</div>
</div>
<div id="templatePlaceholder">
</div>
<div><br></div>
<div class="row">
<input type="hidden" id="localSelectedObjectId" class="hidden" />
<label for="localSelectedObject">Selected Object</label>
<input type="text" class="dealName" id="localSelectedObject" readonly="readonly" placeholder="No object selected"/>
</div>
</div>
</script>
<script id="listTemplate" type="text/x-jquery-tmpl">
<tr>
<td><a class="objectItem" id="${Id}" href="#">${Name}</a></td>
</tr>
</script>
<div id="pagerControl">
<uc1:PagerControl ID="PagerControl1" runat="server" />
</div>
</div>
Раскрывающийся список заполняется непосредственно перед созданием диалога с использованием данных, извлеченных из службы WCF, которая затем привязывается к первому шаблону.
Событие 'change' связывается с раскрывающимся списком, используя команду live для заполнения таблицы (второй шаблон), вызывая службу WCF и проходя через выбранный в данный момент элемент в раскрывающемся списке.
Когда событие изменения запускается в раскрывающемся списке, вызывается LoadObjects:
function LoadObjects(event) {
var dialogDom = event.data.DialogDom;
var searchObj = GetSearchFilters(); // removed irrelevant code here
var listTemplate = searchDom.find('#listTemplate');
var templatePlaceholder = dialogDom.find('#templatePlaceholder');
templatePlaceholder.empty();
templatePlaceholder.append(listTemplate);
var pagerControl = searchDom.find('#pagerControl');
var pagerPlaceholder = dialogDom.find('#pagerPlaceholder');
pagerPlaceholder.append(pagerControl);
var list = GenerateList(
dialogDom,
$('<div></div>'),
searchObj,
Connection('MyUiService', 'GetObjects'));
}
Метод GenerateList () создает объект JQuery с различными методами, включая методы, которые получают данные объектов из службы WCF и связывают их с шаблоном (listTemplate)
Код PagerControl также содержит шаблон, который заполняется одновременно с listTemplate.
Код для listTemplate и пейджера должен был быть помещен вне сценария objectSelectorTemplate, а затем скопирован позже, чтобы предотвратить его удаление при анализе страницы для заполнения раскрывающегося списка.
Все вышеперечисленное прекрасно работает при первом открытии диалогового окна и выборе элемента из раскрывающегося списка. Можно изменять страницы в данных таблицы без проблем, но как только выбранный элемент в раскрывающемся списке изменяется, данные таблицы больше не загружаются. Если я пошагово выполняю код, я вижу, что append () (в методе LoadObjects) удаляет скрипт listTemplate при вставке его в listPlaceholder, что означает, что когда диалог снова загружает данные таблицы, скрипт больше не является там. Чтобы обойти это, я попытался добавить клон вместо:
templatePlaceholder.append(listTemplate.clone());
Это успешно предотвратило удаление сценария listTemplate, однако клонированная копия содержала теги сценария, но не его содержимое, поэтому данные таблицы по-прежнему не загружались. Я искал SO и нашел ответ Джона Ресига на этот вопрос :
Так что я изменил код выше:
var listTemplateCopy = jQuery.extend({}, listTemplate);
templatePlaceholder.append(listTemplateCopy);
Это успешно скопировало тег сценария и его содержимое в listTemplateCopy, но append () удаляет listTemplate, а также listTemplateCopy. Сначала я предположил, что это произошло потому, что extends предназначен для объединения двух (или более) объектов в один объект, но по ответу Джона и из того, что я прочитал в документации, это звучало так, как то, что вы должны использовать для расширения создать копию объекта jquery.
Может кто-нибудь объяснить мне, что именно происходит, и порекомендовать решение выше?
У меня была пара идей:
- сдвигать теги скрипта так, чтобы они окружали только код шаблона. Тогда я мог бы иметь второй шаблонный код вместо того, чтобы добавлять его. Привязка выполняется привязкой к шаблону раскрывающегося списка, а затем к таблице
- используйте другой способ для заполнения раскрывающегося списка, а не шаблон, чтобы упростить страницу и устранить «необходимость» добавления сценариев, так как не будет тега сценария, окружающего весь лот
Я хотел бы получить представление о том, что именно код делает в данный момент, прежде чем приступать к одному из этих подходов.