2017-12-11 4 views
0

Ich habe eine Abfrage für eine Sharepoint-Liste, die einige Daten zurückgibt, aber dann für jedes Element muss ich eine andere Abfrage, um seinen Dokumententyp (Inhaltstyp) zu erhalten, ist das Problem, dass dieser Teil von Der Code wird ausgeführt, nachdem die Seite gerendert wurde.Werte nicht mit Versprechen gefüllt

var cname = getContentTypeOfCurrentItem(listItemValues['ID'].toString()); 
listItemsWithValues['Document Type'] = cname; 


function GetRelatedBillingDocumentsFromList(selectProperties, currentBillCyclePath, clientCode, jobCodes, engagementCode, enhanceFunctions) { 
    $log.info('Retrieving related billing documents for bill cycle with name [' + currentBillCyclePath + ']'); 
    var deferred = $q.defer(); 
    var webUrl = _spPageContextInfo.webAbsoluteUrl; 
    var viewFields = spService.ConvertSelectPropertiesToViewFields(selectProperties); 
    // query must return the documents for the same client but in other bill cycles not the current one 
    var camlQuery = '<View Scope="RecursiveAll">' + viewFields + 
    '<Query>' + 
    '<Where>' + 
    '<And>' + 
    '<Eq>' + 
    '<FieldRef Name="ClientCode" />' + 
    '<Value Type="Text">' + clientCode + '</Value>' + 
    '</Eq>' + 
    '<Neq>' + 
    '<FieldRef Name="ContentType" />' + 
    '<Value Type="Computed">Bill Cycle</Value>' + 
    '</Neq>' + 
    '</And>' + 
    '</Where>' + 
    '</Query>' + 
    '</View>'; 

    var billCyclesListId = '{c23bbae4-34f7-494c-8f67-acece3ba60da}'; 
    spService.GetListItems(billCyclesListId, camlQuery, selectProperties) 
    .then(function (listItems) { 
     var listItemsWithValues = []; 

     if (listItems) { 
     var enumerator = listItems.getEnumerator(); 
     var promises = []; 
     while (enumerator.moveNext()) { 
      var listItem = enumerator.get_current(); 
      var listItemValues = []; 
      selectProperties 
      .forEach(function (propertyName) { 
       var value = listItem.get_item(propertyName); 
       if (propertyName === 'PwC_JobCodesMulti') { 
       jobvalue = ''; 
       value.forEach(function (jobvalues) { 
        jobvalue += jobvalues.get_lookupValue() + ';'; 
       }); 
       listItemValues[propertyName] = jobvalue; 
       } else { 
       listItemValues[propertyName] = value; 
       } 
       //listItemValues[propertyName] = value; 
      }); 

      listItemsWithValues.push(listItemValues); 
     } 

     var cname = getContentTypeOfCurrentItem(listItemValues['ID'].toString()); 
     listItemsWithValues['Document Type'] = cname; 
     } 

     listItemsWithValues.forEach(function (listItem) { 
     var fileDirRef = listItem['FileRef']; 
     var id = listItem['ID']; 
     var title = listItem['Title']; 
     var serverUrl = _spPageContextInfo.webAbsoluteUrl.replace(_spPageContextInfo.webServerRelativeUrl, ''); 
     var dispFormUrl = serverUrl + '/sites/billing/_layouts/15/DocSetHome.aspx?id=' + fileDirRef; 
     //listItem["FileRef"] = dispFormUrl; 
     //listItem["Bill Cycle"] = dispFormUrl; 

     var parentLink = listItem['FileRef']; 
     arrayofstrings = parentLink.split('/'); 
     var billCycleFolderName = arrayofstrings[arrayofstrings.length - 2]; 
     arrayofstrings.pop(); 
     var hyperLink = '<a href="' + arrayofstrings.join('/') + '">' + billCycleFolderName + '</a>'; 
     listItem['Bill Cycle'] = hyperLink; 

     }); 

     var enhancedListItemValues = spService.SpSearchQuery.EnhanceSearchResults(listItemsWithValues, enhanceFunctions); 
     deferred.resolve(listItemsWithValues); 
    }) 
    .catch(function (message) { 
     deferred.reject(); 
    }); 

    return deferred.promise; 
} 

function getContentTypeOfCurrentItem(id) { 

    var clientContext = new SP.ClientContext.get_current(); 
    var oList = clientContext.get_web().get_lists().getByTitle('Bill Cycles'); 
    listItem = oList.getItemById(id); 
    clientContext.load(listItem); 
    listContentTypes = oList.get_contentTypes(); 
    clientContext.load(listContentTypes); 
    clientContext.executeQueryAsync(
    Function.createDelegate(this, getContentTypeOfCurrentItemSucceeded), 
    function (error, errorInfo) { 
     $log.warn('Retrieving list item result failed'); 
     deferred.reject(errorInfo); 
    } 
); 
} 

function getContentTypeOfCurrentItemSucceeded(sender, args) { 
    var ctid = listItem.get_item('ContentTypeId').toString(); 
    var ct_enumerator = listContentTypes.getEnumerator(); 
    while (ct_enumerator.moveNext()) { 
    var ct = ct_enumerator.get_current(); 
    if (ct.get_id().toString() == ctid) { 
     var contentTypeName = ct.get_name(); 
     return contentTypeName; 
    } 
    } 
} 

Wie kann ich chan verspricht hier sicherzustellen, dass der Inhaltstyp Anruf richtig gemacht wird?

+3

[Sie brauchen nicht '$ q.defer()', wenn Sie bereits ein Versprechen] (https: //stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-iavoid-it). – str

+0

Vermeiden Sie die [latente antipattern] (https://stackoverflow.com/q/23803743/1048572? Was ist die-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi

+0

So gibt es eine asynchrone Abfrage bei der 'getContentTypeOfCurrentItem'. Ich nehme an, Sie möchten mehrere asynchrone Abfragen in den 'EnhanceSearchResults' durchführen und dieses Ergebnis zurückgeben? – jervtub

Antwort

2

Ich habe Ihr Beispiel überarbeitet, um die Absicht Ihres Codes zu verstehen. Ich denke, dass Sie die asynchrone Natur der Versprechungen und die Idee von Geltungsbereich/Schließungen besser verstehen müssen (ich glaube nicht, dass Ihr Code überhaupt funktioniert, in vielerlei Hinsicht habe ich eine Rezension in die Datei oldscript.js aufgenommen).

https://embed.plnkr.co/3YcHZzxH4u6ylcA2lJZl/

Mein Beispiel verwendet ein Stub-Objekt Ihren Provider zu simulieren, aber es kurz zu halten, würde ich sagen: Der Schlüssel ist Promise.all, eine Fabrik, die ein neues Versprechen erzeugt, das erfüllt wird, wenn alle Versprechungen aufgelöst.

Sie müssen ein Versprechen für jeden Artikel speichern, der den zukünftigen Wert für jede ID enthält (Ihr Original-Snippet speichert nur die letzte ID, es schien ein Fehler zu sein), und wenn alle behoben sind, können Sie weiterarbeiten Ihre Daten (später, asynchron oder verzögert).

Hoffen, dass es


Ein relevanter Schnipsel hilft ...

function addContentType(listItem){ 
    var promise = getContentTypeOfCurrentItem(listItem.ID.toString()); 
    promise.then(function(cname){ 
    listItem['Document Type'] = cname; 
    }); 
    return promise; 
} 

function processListItems(listItems) { 
var listItemsWithValues = listItems.map(listItemToValue); 

var promises = listItemsWithValues.map(addContentType); 
Promise.all(promises).then(youCanUseTheData); 

function youCanUseTheData(){ 
    /* 
    At this point, each listItem holds the 'Document Type' info 
    */ 
    listItemsWithValues.forEach(function (listItem) { 
    console.log(listItem); 
    }); 
} 
+2

Bitte geben Sie den entsprechenden Code in Ihre Antwort ein, nicht nur einen Link dazu. – Bergi

+0

Ich musste viel Code umgestalten, um besser zu verstehen (und zu testen, dass es funktioniert), der ursprüngliche Code enthielt verschiedene Fehler, ich habe ein Snippet hinzugefügt, aber Sie müssen auf dem Plunk graben, um es im Kontext zu verstehen – sminutoli

+0

https://stackoverflow.com/questions/31299231/how-does-promise-all-work – sminutoli

Verwandte Themen