【发布时间】:2011-11-05 01:45:52
【问题描述】:
请多多包涵,因为它有点复杂,而且我对 JQuery 完全陌生,并试图理解它。
我和我的团队正在为一个 SharePoint 项目开发 WebPart。 WebPart 包含一个用户控件 (SearchControl),该控件具有用于打开包含另一个用户控件 (SelectorControl) 的对话框(使用 jquery ui)的链接。
SelectorControl 包含:
- 使用 JQuery 模板填充的下拉列表 (objTemplates)
- 使用另一个 JQuery 模板填充的表;和
- 只读文本输入,用于显示表中当前选定的项目
SelectorControl 代码:
<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 服务检索的数据创建对话框之前填充下拉列表,然后绑定到第一个模板。
通过调用 WCF 服务并通过下拉列表中当前选定的项目,使用 live 填充表(第二个模板)将“更改”事件绑定到下拉列表。
当下拉列表触发change事件时,调用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,发现John Resig对this question的回复:
所以我把上面的代码改成:
var listTemplateCopy = jQuery.extend({}, listTemplate);
templatePlaceholder.append(listTemplateCopy);
这成功地将脚本标签及其内容复制到 listTemplateCopy,但 append() 会删除 listTemplate 以及 listTemplateCopy。起初我认为这是因为 extend 旨在将两个(或更多)对象合并为一个对象,但从约翰的回应和我在文档中读到的内容来看,听起来 extend 是你应该用来创建一个 jquery 对象的副本。
谁能向我解释到底发生了什么并推荐解决上述问题的方法?
我的一些想法是:
- 将脚本标签移动到仅围绕模板代码。然后我可以将第二个模板代码放在适当的位置,而无需附加它。绑定将通过绑定到下拉列表模板然后绑定到表格来完成
- 使用不同的方式填充下拉列表而不是模板来简化页面并消除附加脚本的“必要性”,因为整个批次不会有脚本标记
在采用这两种方法之前,我想了解代码当前正在做什么。
【问题讨论】:
标签: jquery web-parts jquery-templates