2016-10-20 2 views
0

У меня есть требование изменить значение столбца состояния рабочего процесса SharePoint List.Вложенный клиентContext executeQueryAsync()

Предположим, что у нас может быть от 2 до многих столбцов рабочего процесса в одном списке (приведенный ниже код работает, когда в списке есть 1 столбец состояния рабочего процесса).

Проблема заключается в том, что он имеет несколько столбцов состояния рабочего процесса, он обновляет только последний столбец, поскольку есть вложенные вызовы executeQueryAsync.

Я пробовал то же самое с отсрочкой/обещанием, а также - см. Второй блок кода.

<script type="text/javascript"> 
ExecuteOrDelayUntilScriptLoaded(initialize, "sp.js"); 

//Get our objects 
function initialize() { 
    var t0 = performance.now(); 
    var context = new SP.ClientContext.get_current(); 
    var web = context.get_web(); 
    var list = web.get_lists().getById(_spPageContextInfo.pageListId) 
    var fieldCollection = list.get_fields(); 
    var spField; 
    context.load(fieldCollection); 
    context.executeQueryAsync(Function.createDelegate(this, onFieldCollectionSucceeded), Function.createDelegate(this, onListDataFailed)); 

    function onFieldCollectionSucceeded(sender, args) { 
     var fieldEnumerator = fieldCollection.getEnumerator(); 
     while (fieldEnumerator.moveNext()) { 
      var field = fieldEnumerator.get_current(); 
      var fType = field.get_fieldTypeKind(); 
      //Value 28 correspond to SPWorkflowStatus 
      if (fType === 28) { 
       console.log(fieldEnumerator.get_current().get_title() + ": " + fType); 

       spField = field; 
       context.load(spField, "SchemaXml"); 
       context.executeQueryAsync(Function.createDelegate(this, onFieldSucceeded), Function.createDelegate(this, onListDataFailed)); 
      } 
     } 
    } 

    function onFieldSucceeded(sender, args) { 
     console.log("Schema changes processing for column: " + spField.get_title()); 
     var schema = spField.get_schemaXml(); 
     var newSchema = schema.replace('Abgelehnt', 'Rejected'); 
     spField.set_schemaXml(newSchema); 
     spField.update(); 
     context.executeQueryAsync(
      Function.createDelegate(this, schemaChanged), 
      Function.createDelegate(this, onListDataFailed)); 
    }; 

    function schemaChanged(sender, args) { 
     console.log('Field Schema Updated'); 
    } 

    function onListDataFailed(sender, args) { 
     console.log('List Data fetch failed. ' + args.get_message() + 'n' + args.get_stackTrace()); 
    }; 

    var t1 = performance.now(); 
    console.log("Total Execution Time " + (t1 - t0) + " milliseconds.") 
}; 

<script type="text/javascript"> 
//http://johnliu.net/blog/2015/12/convert-sharepoint-jsoms-executequeryasync-to-promise-in-the-prototype 
ExecuteOrDelayUntilScriptLoaded(registerJsomPromise, "sp.js"); 
ExecuteOrDelayUntilScriptLoaded(initialize, "sp.js"); 

function initialize() { 
    var t0 = performance.now(); 
    var context = new SP.ClientContext.get_current(); 
    var web = context.get_web(); 
    var list = web.get_lists().getById(_spPageContextInfo.pageListId) 
    var fieldCollection = list.get_fields(); 
    var spField; 
    context.load(fieldCollection); 
    context.executeQueryAsync(Function.createDelegate(this, onFieldCollectionSucceeded), Function.createDelegate(this, onListDataFailed)); 
}; 

function onFieldCollectionSucceeded(sender, args) { 
    var fieldEnumerator = fieldCollection.getEnumerator(); 
    while (fieldEnumerator.moveNext()) { 
     var field = fieldEnumerator.get_current(); 
     var fType = field.get_fieldTypeKind(); 
     //Value 28 correspond to SPWorkflowStatus 
     if (fType === 28) { 
      console.log(fieldEnumerator.get_current().get_title() + ": " + fType); 

      spField = field; 
      context.load(spField, "SchemaXml"); 

      var promise = context.executeQuery(); 
      setTimeout(function() { }, 500); 

      promise.done(function() { 
       console.log("Schema changes processing for column: " + spField.get_title()); 
       var schema = spField.get_schemaXml(); 
       var newSchema = setSchema(schema); 
       spField.set_schemaXml(newSchema); 
       spField.update(); 
       context.load(spField); 

       context.executeQueryAsync(
        Function.createDelegate(this, schemaChanged), 
        Function.createDelegate(this, onListDataFailed)); 
      }); 
      promise.then(function (sArgs) { 
       console.log('Field Schema Updated'); 
       //sArgs[0] == success callback sender 
       //sArgs[1] == success callback args 
      }, function (fArgs) { 
       //fArgs[0] == fail callback sender 
       //fArgs[1] == fail callback args. 
       //in JSOM the callback args aren't used much - 
       //the only useful one is probably the get_message() 
       //on the fail callback 
       var failmessage = fArgs[1].get_message(); 
      }); 
      //context.executeQueryAsync(Function.createDelegate(this, onListDataSucceeded), Function.createDelegate(this, onListDataFailed)); 
     } 
    } 
} 

function schemaChanged(sender, args) { 
    console.log('Field Schema Updated'); 
} 

function onListDataFailed(sender, args) { 
    console.log('List Data fetch failed. ' + args.get_message() + 'n' + args.get_stackTrace()); 
}; 

var t1 = performance.now(); 
console.log("Total Execution Time " + (t1 - t0) + " milliseconds.") 


function registerJsomPromise() { 

    SP.ClientContext.prototype.executeQuery = function() { 
     var deferred = $.Deferred(); 
     this.executeQueryAsync(
      function() { deferred.resolve(arguments); }, 
      function() { deferred.reject(arguments); } 
     ); 
     return deferred.promise(); 
    }; 


} 

ответ

0

Выполнить асинхронный запрос изменяет состояние итератора. Вот почему у вас странное поведение. Вы должны загружать свои поля, обновлять их и выполнять один сингл в конце времени, чтобы фактически обновить материал. Единственная проблема с этим подходом заключается в том, что если вы в какой-то момент не выполняете код, все обновления будут отложены. Поэтому требуется тщательная обработка ошибок.

+0

Согласовано, однако требование состоит в том, чтобы обновить много столбцов/полей Workflow, поэтому один одиночный кадр невозможен, я думаю. Сегодня утром я удалил часть итератора и попытался обновить один за другим, но все равно не повезло, проблема с многопоточным я подозреваю. – user3674148

+0

ExecuteOrDelayUntilScriptLoaded (function() {initialize ("Approval")}, "sp.js"); ExecuteOrDelayUntilScriptLoaded (function() {initialize ("Feedback")}, "sp.js"); – user3674148

Смежные вопросы