0

更新

我现在尝试了一种新方法。这在我第一次调用它时有效,但第二次它告诉我由于某种原因尚未启动收集。此代码片段的测试功能中的注释将澄清我的问题。

Javascript:

function test(){
    //this first call works
    countRetrieve('Very', 'Difficult');
    //this second call generates error that collListItem hasnt been initiated
    countRetrieve('Less', 'Interesting');
}   


function countRetrieve(grade, title) {
    var siteUrl = '/sites/MySite';
    var clientContext = new SP.ClientContext(siteUrl);
    var oList = clientContext.get_web().get_lists().getByTitle('Summary');

    var camlQuery = new SP.CamlQuery();

    camlQuery.set_viewXml('<View><Query><Where>' +
    '<And>' +
    '<Eq><FieldRef Name=\'Grad\'/><Value Type=\'Text\'>' +
    grade +
    '</Value></Eq>' +
    '<Eq><FieldRef Name=\'Title\'/><Value Type=\'Text\'>' +
    title +
    '</Value></Eq>' +
    '</And>' +  
    '</Where></Query></View>');
    this.collListItem = oList.getItems(camlQuery);
    clientContext.load(collListItem);
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onRetrieveQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onRetrieveQuerySucceeded(sender, args) {
    listItemEnumerator = collListItem.getEnumerator();

    while (listItemEnumerator.moveNext()) {
        var oListItem = listItemEnumerator.get_current();
        itemId = oListItem.get_id();
        itemCount = oListItem.get_item('Count');
    }
    updateCount();
}



function updateCount() {
    var clientContext = new SP.ClientContext('/sites/MySite');
    var oList = clientContext.get_web().get_lists().getByTitle('Summary');

    this.oListItem = oList.getItemById(itemId);
    //update the count, raise it by one
    var c = itemCount + 1;
    oListItem.set_item('Count', c);

    oListItem.update();

    clientContext.executeQueryAsync(Function.createDelegate(this, this.onUpdateSucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onUpdateSucceeded(sender, args){
    alert('item count updated');
}

我试图检索列表中“计数”列的当前值,然后将该值增加 1。但是我收到一个错误,告诉我集合尚未初始化。

它没有在this.collListItem = oList.getItems(camlQuery);中初始化吗??

这个功能可能完全错误,我非常感谢有关如何执行此任务的提示,因为我是 Sharepoint 和 Javascript 的新手。

这是我的代码(javascript):

function countUpdate() {
            var siteUrl = '/sites/MySite';
            var clientContext = new SP.ClientContext(siteUrl);
            var oList = clientContext.get_web().get_lists().getByTitle('Summary');

            var camlQuery = new SP.CamlQuery();

            camlQuery.set_viewXml('<View><Query><Where>' +
            '<And>' +
            '<Eq><FieldRef Name=\'Grade\'/><Value Type=\'Text\'>' +
            'Really' +
            '</Value></Eq>' +
            '<Eq><FieldRef Name=\'Property\'/><Value Type=\'Text\'>' +
            'Narrow' +
            '</Value></Eq>' +
            '</And>' +  
            '</Where></Query></View>');
            this.collListItem = oList.getItems(camlQuery);
            clientContext.load(collListItem);

            clientContext.executeQueryAsync(Function.createDelegate(this, this.onUpdateQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));

            //update
            var listItemEnumerator = collListItem.getEnumerator();
            while (listItemEnumerator.moveNext()) {
                var oListItem = listItemEnumerator.get_current();
                var count = oListItem.get_item('Count');
                oListItem.set_item('Count', '40');
                oListItem.update();
            }
            clientContext.executeQueryAsync(Function.createDelegate(this, this.onUpdateQuerySucceeded),Function.createDelegate(this, this.onQueryFailed));
        }
4

3 回答 3

1

正如回答的那样,您的问题在于 AJAX 的异步性质。您的电话已拨打,其他代码在返回之前立即继续。所以你需要的是一个“处理程序”——一个在你的请求完成时调用的函数,它将处理它返回的数据。

executeQueryAsync 将方法(函数)“succeededCallback”作为其第一个参数 - 您需要创建该方法并将其提供给此调用(没有括号 - 您想要传递对函数的引用,而不是运行它)。该方法将在请求完成时自动调用,并再次自动将调用结果作为第一个参数包含在内。

查看您的代码并尽可能简单化,您将不得不将三个函数链接在一起:

1) 设置初始呼叫和完成呼叫 2)。

2) 接受第一次调用的结果,对它们采取行动,设置第二次调用,完成后调用 3)

3) 接受第二次调用的结果,对它们采取行动。

您可以使用内置的 SP 功能,但老实说我觉得它们有点麻烦。我在这里构建了自己的 AJAX 抽象来执行此操作:

http://depressedpress.com/javascript-extensions/dp_ajax/

实现有点不同,但想法完全一样——也许看看那里的一些例子可能会让事情变得更清晰。

希望这可以帮助。值得一提的是,与您相处融洽:这是“在真正得到它之前没有人得到它”的事情之一,这似乎是第一次对任何人来说都是一个绊脚石。

于 2012-09-17T13:16:51.763 回答
0

您需要在 onUpdateQuerySucceeded 函数中继续执行 - 在该列表将没有任何信息之前,因为需要将请求发送到服务器并在获取项目之前对响应进行处理。

正是出于这个原因,这些函数被称为 XXXXAsync - 调用它不会立即给出结果,而是在成功回调中异步评估。

于 2012-09-16T18:24:13.357 回答
0

感谢吉姆的回答。不仅问题所有者发现您的帖子有用。

为了简化事情,我发布了一个示例:此代码可以SPListItem通过单击一个来更新多个CheckBox

var appOpsUrl = '/sites/AppOpsRep';
var coll;

function UpdateTargetInReport(checkBox, refValueOne, refValueTwo)
{
    var clientContext = new SP.ClientContext.get_current();
    var list = clientContext.get_web().get_lists().getByTitle('SLA Fulfillment');
    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml('<View><Query><Where><And><Eq><FieldRef Name=\'Application\' /><Value Type=\'Text\'>' + refValueOne + '</Value></Eq><Eq><FieldRef Name=\'Metric_x0020_name\' /><Value Type=\'Text\'>' + refValueTwo + '</Value></Eq></And></Where></Query></View>');
    coll = list.getItems(camlQuery);
    clientContext.load(coll);
    clientContext.executeQueryAsync(Function.createDelegate(this, function(){ UpdateTargetInReport_onQuerySucceeded(refValueTwo, checkBox); }), Function.createDelegate(this, function(sender,args) { UpdateTargetInReport_onQueryFailed(sender, args, checkBox); })); 
}

function UpdateTargetInReport_onQuerySucceeded(refValueTwo, checkBox)
{
    var clientContext = new SP.ClientContext.get_current();
    var listItemEnumerator = coll.getEnumerator();
    while(listItemEnumerator.moveNext()) 
    {
        var listItem = listItemEnumerator.get_current();
        listItem.set_item('In_x0020_Report', checkBox.checked);
        listItem.update(); 
    }
    clientContext.executeQueryAsync(Function.createDelegate(this, function() { UpdateTargetInReport_onUpdateQuerySucceeded(refValueTwo); }), Function.createDelegate(this, function(sender,args) { UpdateTargetInReport_onUpdateQueryFailed(sender, args, checkBox); } )); 
}

function UpdateTargetInReport_onQueryFailed(sender, args, checkBox) 
{
    SP.UI.Notify.addNotification('Request failed. ' + args.get_message());
    checkBox.checked = !checkBox.checked; 
}

function UpdateTargetInReport_onUpdateQuerySucceeded(refValueTwo)
{
    SP.UI.Notify.addNotification(refValueTwo + ' updated successfully');
}

function UpdateTargetInReport_onUpdateQueryFailed(sender, args, checkBox)
{
    SP.UI.Notify.addNotification('Request failed. ' + args.get_message());
    checkBox.checked = !checkBox.checked;
}
于 2013-02-05T12:40:52.323 回答