Mam Angular SPA działające na stronie SharePoint 2013. W kodzie używam $ q do pobierania danych z 10 różnych list programu SharePoint przy użyciu usługi REST, a następnie łączenia ich w jeden obiekt JSON w celu użycia w siatce. Kod działa i wyprowadza zamierzone scalone dane, ale jest nieszczelny i po chwili zawiesza przeglądarkę.Jak połączyć wyniki REST call w aplikacji Angular, bardziej wydajnie
Oto kod w serwisie:
factory.getGridInfo = function() {
var deferred = $q.defer();
var list_1a = CRUDFactory.getListItems("ListA", "column1,column2,column3");
var list_1b = CRUDFactory.getListItems("ListB", "column1,column2,column3");
var list_2a = CRUDFactory.getListItems("ListC", "column4");
var list_2b = CRUDFactory.getListItems("ListD", "column4");
var list_3a = CRUDFactory.getListItems("ListE", "column5");
var list_3b = CRUDFactory.getListItems("ListF", "column5");
var list_4a = CRUDFactory.getListItems("ListG", "column6");
var list_4b = CRUDFactory.getListItems("ListH", "column6");
var list_5a = CRUDFactory.getListItems("ListI", "column7");
var list_5b = CRUDFactory.getListItems("ListJ", "column7");
$q.all([list_1a, list_1b, list_2a, list_2b, list_3a, list_3b, list_4a, list_4b, list_5a, list_5b])
.then(function(results){
var results_1a = results[0].data.d.results;
var results_1b = results[1].data.d.results;
var results_2a = results[2].data.d.results;
var results_2b = results[3].data.d.results;
var results_3a = results[4].data.d.results;
var results_3b = results[5].data.d.results;
var results_4a = results[6].data.d.results;
var results_4b = results[7].data.d.results;
var results_5a = results[8].data.d.results;
var results_5b = results[9].data.d.results;
var combined_1 = results_1a.concat(results_1b);
var combined_2 = results_2a.concat(results_2b);
var combined_3 = results_3a.concat(results_3b);
var combined_4 = results_4a.concat(results_4b);
var combined_5 = results_5a.concat(results_5b);
for(var i = 0; i < combined_1.length; i++){
var currObj = combined_1[i];
currObj["column4"] = combined_2[i].column4;
currObj["column5"] = combined_3[i].column5;
currObj["column6"] = combined_4[i].column6;
currObj["column7"] = combined_5[i].column7;
factory.newObjectArray[i] = currObj;
}
deferred.resolve(factory.newObjectArray);
},
function (error) {
deferred.reject(error);
});
return deferred.promise;
};
Oto wezwanie REST w CRUDFactory:
factory.getListItems = function (listName, columns){
var webUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('"+listName+"')/items?$select="+columns+"&$top=5000";
var options = {
headers: { "Accept": "application/json; odata=verbose" },
method: 'GET',
url: webUrl
};
return $http(options);
};
I wtedy oto nieco kontroler:
$scope.refreshGridData = function(){
$scope.hideLoadingGif = false;
$scope.GridData = "";
GlobalFactory.getGridInfo()
.then(function(){
$scope.GridData = GlobalFactory.newObjectArray;
$scope.hideLoadingGif = true;
});
};
UPDATE 1: Na życzenie, oto HTML (tylko prosty div, który w e're użyciu kątowej-UI-siatkę na)
<div ui-grid="GridOptions" class="grid" ui-grid-selection ui-grid-exporter ui-grid-save-state></div>
Kod ten rozpoczyna się poprzez uznanie niektórych połączeń, a następnie używa $ q.all iteracyjne nad połączeniami i inne dane. Następnie przechowuje wyniki i łączy je w 5 tablic łącznie. Następnie, ponieważ struktura mojej listy jest poprawna i statyczna, jestem w stanie powtórzyć jeden z scalonych tablic i pobrać dane z innych tablic do jednej głównej tablicy, którą przypisuję do fabryki.newObjectArray, którą deklaruję jako globalny w mojej usłudze i jako moje źródło danych w sieci.
Kod działa i nie wykopie żadnych błędów, ale problem dotyczy (moim zdaniem) funkcji "getGridInfo". Jeśli nie skomentuję żadnego z wywołań REST, przeglądarka używa 45 MB danych, które nie zostaną odebrane przez GC, a następnie są dodawane do każdego kliknięcia, aż do zakończenia sesji lub awarii. Jeśli skomentuję wszystkie połączenia oprócz jednej, moja strona używa tylko 18,4 MB pamięci, co jest wysokie, ale mogę z tym żyć.
Więc jaka jest umowa? Czy muszę coś gdzieś zniszczyć? Jeśli tak, to co i jak? Czy to odnosi się do funkcji REST, której używam?
UPDATE 2: spowodować Zwrot że siatka jest za pomocą (The factory.newObjectArray) zawiera w sumie 5,450 elementów, a każdy element ma około 80 właściwości po połączeniu. Powyższy kod jest uproszczony i pokazuje ciągnięcie kilku kolumn na liście, ale w rzeczywistości generuję 5-10 kolumn na liście.
Nie widzę nic zasadniczo nie tak z Twoim kodem. Z której przeglądarki korzystasz? – link64
IE11 lub FF 38,2 (brak dostępu do Chrome w tym środowisku) – Josey
To wstyd, ponieważ Chrome ma profilera, który może pokazać, co się dzieje. Czy możesz pokazać znaczniki? Ta odpowiedź http://stackoverflow.com/a/25193339/1248716 sugeruje, że wycieki są powodowane przez elementy DOM tworzone przez Ng-repeat i nie są one wypuszczane. – link64