0

アップデート

私は今、新しいアプローチを試みました。これは、1 回呼び出すと機能しますが、2 回目には何らかの理由でコレクションが開始されていないことがわかります。このコード スニペットのテスト関数のコメントは、私の問題を明確にします。

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"を取ります。そのメソッドを作成し、この呼び出しに渡す必要があります(パラメーターなしで、関数への参照を渡し、実行する必要はありません)。そのメソッドは、リクエストが完了すると自動的に呼び出され、再び自動的に、最初の引数として呼び出しの結果が含まれます。

コードを見て、可能な限り単純化すると、次の3つの関数をチェーン化する必要があります。

1)最初の呼び出しと完了した呼び出しを設定します2)。

2)最初の呼び出しからの結果を受け入れ、それらに基づいて行動し、2番目の呼び出しを設定し、完了したら呼び出しを行います3)

3)2回目の呼び出しの結果を受け入れ、それに基づいて行動します。

組み込みのSP機能を使用することもできますが、正直少し面倒です。私はここでこれを行うために独自のAJAXアブストラクションを構築しました:

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

実装は少し異なりますが、アイデアはまったく同じです。おそらく、そこにあるいくつかの例を見ると、物事がより明確に焦点を当てられる可能性があります。

お役に立てれば。あなたが良い仲間にいる価値があるということは少しだけですが、これは「本当にそれを手に入れるまで誰もそれを手に入れられない」ものの1つであり、ほとんどの人にとって初めての障害のようです。

于 2012-09-17T13:16:51.763 に答える
0

onUpdateQuerySucceeded関数で実行を継続する必要があります。アイテムを取得する前にリクエストをサーバーに送信し、レスポンスを処理する必要があるため、リストに情報が含まれなくなります。

関数は、まさにこの理由でXXXXAsyncと呼ばれます。これを呼び出すと、すぐには結果が得られませんが、成功コールバックでは非同期に評価されます。

于 2012-09-16T18:24:13.357 に答える
0

答えてくれてありがとうジム。質問の所有者だけがあなたの投稿を役に立つとは限りません。

物事を簡単にするために、サンプルを投稿しています。このコードはSPListItem、1 つをクリックすることで複数のを更新できます。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 に答える