我有一個在SharePoint 2013頁面上運行的Angular SPA。在代碼中,我使用$ q從10個不同的SharePoint列表中使用REST提取數據,然後將它們合併爲一個用於網格的JSON對象。該代碼運行並輸出預期的合併數據,但它有點漏洞並且在一段時間後崩潰瀏覽器。如何更有效地將REST調用結果合併到Angular應用程序中
下面是在服務代碼:
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;
};
下面是CRUDFactory的REST調用:
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);
};
然後這裏的控制器位:
$scope.refreshGridData = function(){
$scope.hideLoadingGif = false;
$scope.GridData = "";
GlobalFactory.getGridInfo()
.then(function(){
$scope.GridData = GlobalFactory.newObjectArray;
$scope.hideLoadingGif = true;
});
};
更新1:每個請求,這是HTML(只是一個簡單的div,w e're使用角上的UI網)
<div ui-grid="GridOptions" class="grid" ui-grid-selection ui-grid-exporter ui-grid-save-state></div>
此代碼首先聲明瞭一些得到調用,然後使用$ q.all遍歷調用和獲取數據。然後它存儲結果並將它們合併爲5個總數組。然後,因爲我的列表結構是正確的和靜態的,所以我可以遍歷其中一個合併數組,並將數據從其他數組抽取到一個主數組中,我將其分配給factory.newObjectArray,我聲明爲一個全球性的服務,並用作我的網格數據源。
該代碼運行並不踢任何錯誤,但問題是(我相信)「getGridInfo」函數。如果我沒有註釋掉任何REST調用,那麼瀏覽器會使用45 MB數據,這些數據不會被GC拾取,然後每複製一次,直到會話結束或崩潰。如果我只將一個電話註釋掉,我的頁面只能使用18.4 MB的內存,這很高,但我可以忍受。
那麼有什麼交易?我需要摧毀某個地方的東西嗎?如果是這樣,什麼和如何?或者這是否與我正在使用的REST函數有關?
更新2:網格正在使用的返回結果(factory.newObjectArray)包含總共5,450個項目,每個項目在合併之後具有大約80個屬性。上面的代碼被簡化了,並且顯示了每個列表中的幾個列的拉動,但實際上,我將每列拉動5-10列。
我看不出任何根本上錯誤的代碼。你正在使用哪種瀏覽器? – link64
IE11或FF 38.2(在此環境中無法訪問Chrome) – Josey
這真是一個恥辱,因爲chrome具有可以向您顯示正在發生的事情的分析器。你可以顯示標記嗎?這個答案http://stackoverflow.com/a/25193339/1248716表明泄漏是由通過ng-repeat創建的DOM元素引起的,並且不會被釋放。 – link64