【发布时间】:2014-02-01 01:55:00
【问题描述】:
我仍在为在可视化 Web 部件上获得一系列延迟承诺而苦苦挣扎。最终目标是将某些 DIV 标记的颜色更改为 SPList 中引用的颜色。
我最初让这段代码处理从列表中查找数据的单个请求,但我现在正在寻找一个请求链。首先是从 window.location.href 属性中查找子站点的名称。尽管此代码正在检索子站点名称,但将其视为输入,这可能是我的第一个错误,也许我应该从 SPWeb 对象中获取它。然后第二个在 where 子句中使用这个值从第二个调用中检索正确的数据到另一个列表。
因此,如果目前有代码可以工作,但是是断断续续的。我想我没有在正确的地方调用 .resolve() ,而且在调用线程使用预期结果之前异步代码是否已经完成只是运气。因此,它在处理器之神的怀抱中,可能工作时间为 50:50。这至少证明我的 jQuery 代码正在产生预期的结果。
我有两个函数对两个不同的 DIV 元素做几乎完全相同的事情。这就是我目前所拥有的。
function alterMenuColour(id) {
getMenuItemfromURLValue(window.location.href).done(function (urlSelection) {
var colkey = 0; //this is the key for the list collection array. This needs to be uneque for each different call to retrieveListItems.
var promise = retrieveListItems('/sites/OMGIntranet/OMGCentral/', 'MenuItemList', '<View><Query><Where><Eq><FieldRef Name=\'MenuItem\'/><Value Type=\'Text\'>' + urlSelection + '</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>', 'Id,MenuColour,BarColour', colkey);
var collMenuListItem = collListItem[colkey];
promise.done(
function (collMenuListItem) {
var listItemEnumerator = collMenuListItem.getEnumerator();
var oListItem;
while (listItemEnumerator.moveNext()) {
oListItem = listItemEnumerator.get_current();
}
var menus = getChildElementsByType(document, id, 'div');
jQuery(menus).children("div").each(function () {
jQuery(this).css("background", oListItem.get_item('MenuColour'));
});
},
function (sender, args) {
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
);
});
}
function alterBarColour() {
getMenuItemfromURLValue(window.location.href).done(function (urlSelection) {
var colkey = 1; //this is the key for the list collection array. This needs to be uneque for each different call to retrieveListItems.
var barpromise = retrieveListItems('/sites/OMGIntranet/OMGCentral/', 'MenuItemList', '<View><Query><Where><Eq><FieldRef Name=\'MenuItem\'/><Value Type=\'Text\'>' + urlSelection + '</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>', 'Id,MenuColour,BarColour', colkey);
var collBarListItem = collListItem[colkey];
barpromise.done(
function (collBarListItem) {
var listItemEnumerator = collBarListItem.getEnumerator();
var oListItem;
while (listItemEnumerator.moveNext()) {
oListItem = listItemEnumerator.get_current();
}
var bar = document.getElementsByClassName('SectionMenuBar');
jQuery(bar).each(function () {
jQuery(this).css("background", oListItem.get_item('BarColour'));
});
},
function (sender, args) {
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
);
});
}
我已经创建了一个 getMenuItemfromURLValue(url) 函数,如果前面描述过,它就是获取子站点名称的方法。
function getMenuItemfromURLValue(url) {
var colkey = 2; //this is the key for the list collection array. This needs to be uneque for each different call to retrieveListItems.
var promise = retrieveListItems('/sites/OMGIntranet/OMGCentral/', 'SectionMenuAssignmentList', '<View><Query><OrderBy><FieldRef Name=\'ID\'/></OrderBy></Query></View>', 'MenuItemLookup', colkey);
var collSelectionMenuAssignemntListItem = collListItem[colkey];
return promise.then(
function (collSelectionMenuAssignemntListItem) {
var listItemEnumerator = collSelectionMenuAssignemntListItem.getEnumerator();
var oListItem;
while (listItemEnumerator.moveNext()) {
oListItem = listItemEnumerator.get_current();
if (isStringMatch(decodeURI(url), oListItem.get_item('MenuItemLookup').$2d_1)) {
return oListItem.get_item('MenuItemLookup').$2d_1;
}
}
},
function (sender, args) {
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
);
}
我正在尝试编写可重用的代码,但让我感到震惊的是,当使用 .then() 等延迟方法时,它更难理解
我有一个从 SharePoint SPList 获取列表数据的功能,该功能在同一主题上再次可重复使用:
//http://www.shillier.com/archive/2013/03/04/using-promises-with-the-javascript-client-object-model-in-sharepoint-2013.aspx
function retrieveListItems(siteUrl, list, calm, include, collkey) {
var deferred = $.Deferred();
var clientContext
if (siteUrl == null) {
clientContext = sharePointCurrentClientContext();
} else {
clientContext = new SP.ClientContext(siteUrl);
}
var oList = clientContext.get_web().get_lists().getByTitle(list);
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml(calm);
if (typeof this.collListItem === 'undefined') {
this.collListItem = [];
}
this.collListItem.add(collkey, oList.getItems(camlQuery));
if (include == null) {
clientContext.load(collListItem[collkey]);
} else {
clientContext.load(collListItem[collkey], 'Include(' + include + ')');
}
clientContext.executeQueryAsync(Function.createDelegate(this, function () { deferred.resolve(collListItem[collkey]) }), Function.createDelegate(this, function (sender, args) { deferred.reject(sender, args); }));
return deferred.promise();
}
最初,当我编写这个函数时,唯一能弄清楚如何成功返回数据的方法是在一个名为 collListItem 的全局列表集合对象中。这太可怕了,我讨厌这个,并一直试图删除它,但到目前为止没有成功。虽然它确实有效,并且在阅读和阅读和阅读之后,有些人建议不能通过延迟方法返回对象,并且必须将它们链接起来才能传递数据。这再次让我回到能够拥有可重用的代码。
【问题讨论】:
-
.done()方法的第二个参数似乎是错误处理程序,但这不是.done()的工作方式。当然,您可以通过这种方式指定其他处理程序,但它们都将是成功处理程序,而不是错误处理程序 - 并且都将接受完全相同的参数列表 - 用于解决承诺的值/对象。 -
语句
var collMenuListItem = collListItem[colkey];、var collBarListItem = collListItem[colkey];和var collSelectionMenuAssignemntListItem = collListItem[colkey];是多余的。而collMenuListItem、collBarListItem和collSelectionMenuAssignemntListItem稍后在各自的外部函数中使用,它们都是内部函数的形式变量,因此与之前声明的变量不同。 -
感谢甜菜根-甜菜根。是的,你对 .done() 的看法是正确的,我正在尝试交换它们,正如你所看到的,我不小心得到了一个 .done() 和一个 .then()。反复阅读定义后,我仍然无法找出区别。我还读到它们是可以互换的,这是错误的,因为就像你说的官方文档给了它们不同的论点。
-
是的,我一直在为内部函数的概念和传递变量而苦苦挣扎。我的 javascript 理解还是很基础的。
标签: javascript jquery sharepoint web-parts jquery-deferred