Синхронизация вызовов Ajax и выполнение QueryAsync SharePoint JS CSOM

У меня проблема с синхронизацией вызовов с использованием Rest Api и объектной модели JavaScript.

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

У меня есть небольшая коллекция идентификаторов, и я просматриваю эту коллекцию и делаю несколько вызовов ajax с каждым из этих элементов.

Результатом этой операции является выполнение некоторых задач и обновление моего пользовательского интерфейса после завершения всех этих операций для обновления моего пользовательского интерфейса и отображения некоторых значков.

Я ожидаю, что 3 значка будут отображаться только для моих трех первых элементов.

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

Я знаю, что есть некоторые проблемы с синхронизацией моих вызовов executeQueryAsync, я узнал об объекте jQuery Deferred, я пытался их использовать, но безрезультатно.

Ниже вы найдете скриншоты того, что я ожидаю.

Ожидал :

https://onedrive.live.com/redir?resid=E2C3CC814469DA54!3070&authkey=!AEf_C0XGDwfuFRY&v=3&ithint=photo%2cpng

Каким будет хороший способ использования deferred ? Может ли кто-нибудь помочь?

Большое спасибо

Эльмидо

Это моя основная функция для переопределения дисплея:

(function () {

var accordionContext = {};
accordionContext.Templates = {};

// Be careful when add the header for the template, because it's will break the default list view render 
accordionContext.Templates.Item = itemTemplate;

// Add OnPostRender event handler to add accordion click events and style 
accordionContext.OnPreRender = [];
accordionContext.OnPreRender.push(function () {
    $(function () {
        IsCurrentUserMemberOfGroup("TEST Owners");
        **$.when(IsUserApprover(arrayOfIDS).done(function () {
            displayIcons();
        }));**
    });
});
accordionContext.OnPostRender = [];
accordionContext.OnPostRender.push(function () {
    $(function () {
        accordionOnPostRender();
        fixColumns();
        audit.relativeUrl = _spPageContextInfo.webAbsoluteUrl;
    });
});

SPClientTemplates.TemplateManager.RegisterTemplateOverrides(accordionContext);
})();

Функция, в которой у меня возникла проблема

function IsUserApprover(auditTab) {

var dfd = $.Deferred();

audit.tabIcons = new Array();

for (var i = 0; i < auditTab.length; i++) {

    var uri = _spPageContextInfo.webAbsoluteUrl + "/_api/web/Lists/GetByTitle('Audit')/items?$select=UserID&$filter=ID eq " + auditTab[i] + "";
    var call = $.ajax({
        url: uri,
        type: "GET",
        dataType: "JSON",
        async: false,
        headers: {
            "Accept": "application/json;odata=verbose"
        }
    });

    call.done(function (data, status, jqxhr) {

        SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () {

            var userId = data.d.results[0].UserID;
            var context = SP.ClientContext.get_current();

            var auditor = context.get_web().ensureUser(userId);
            context.load(auditor);

            //I think the problem is here because I don't know how to handle this call
            context.executeQueryAsync(userLoaded, userFailed);

            function userLoaded() {
                var auditorId = auditor.get_id();
                checkAuditorValidator(auditorId);
                dfd.resolve();
            }

            function userFailed(sender, args) {
                alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());

            }
        });


    });

    call.fail(function (jqxhr, status, error) {
        alert(JSON.stringify(error))
        dfd.reject();
    });

}

return dfd.promise();
}



function checkAuditorValidator(auditorId) {


var uri = _spPageContextInfo.webAbsoluteUrl + "/_api/web/Lists/GetByTitle('SecurityMgmt')/items?" +
           "$select=Auditeur/ID,Validateur/ID" +
           "&$expand=Auditeur/ID,Validateur/ID" +
           "&$filter=(Auditeur/ID eq '" + auditorId + "') and (Validateur/ID eq '" + _spPageContextInfo.userId + "')";

var call = $.ajax({
    url: uri,
    type: "GET",
    dataType: "JSON",
    async: false,
    headers: {
        "Accept": "application/json;odata=verbose"
    }
});

call.done(function (data, status, jqxhr) {

    if (data.d.results.length > 0) {

        if (audit.UserAdmin) {

            audit.tabIcons.push(true);
        }
    }
    else {
        audit.tabIcons.push(false);
    } 
});

call.fail(function (jqxhr, status, error) {
    alert(JSON.stringify(error))

});
}

person Abdel    schedule 20.08.2014    source источник


Ответы (1)


Начиная с Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), синхронные запросы в основном потоке устарели из-за негативного влияния на работу пользователя.

Вам следует избегать синхронных вызовов ajax...

У меня была та же проблема, и я решил ее, добавив идентификатор во время пользовательского рендеринга полей (элементов), при пострендеринге вызывая мою службу асинхронно и в соответствии с результатом редактируя страницу OnPreRender, используя ранее добавленные идентификаторы.

Я также сделал несколько хаков... например, переопределив стандартную функцию RenderItemTemplate. Да, я знаю, это не очень чисто, но работает как шарм.

person Emaborsa    schedule 15.06.2017