仓库正在使用的内部Web软件。它包含一个订单表,其中包含需要扫描并准备交付的物品。
它有3个排序选项,12个主要和次要过滤器。该表由ng-repeat创建,并且有很多范围变量的引用。
它包含一个主要数组,里面有大约2000个对象,并且还有一些对象助手 - 有些很小,有些很大。
主阵列需要每分钟刷新一次以刷新表格,因为有几个人同时使用它。
数组示例:
[0:{Barcode:"1234", Description:"Hisense 50 Inch Quad Core UHD 4K Smart Led TV", Docbal: 0, Docdate:"17/10/2017", Docnum:111111, FastOrder:0, GrpCode:111, NotInStock:true, Notes:"Hello", OnHand:0, OpenQty:1, OrderNumber:1736604, PartOfNotInStock:true, Total:2123, cntOrdersToDemand:6, commited:true, isMultiple:false, multipleChecked:true, relevantStock:0, scanned:0, shelf:null}]
每次扫描都会执行一系列事件,这些事件在客户端对象中包含大量数据搜索和更新。
几乎所有的函数和变量都在范围内,并被ng-click等调用和使用。
一开始没有性能问题,因为阵列非常小,但现在它变大了,我看到程序中有多达60,000个观察者(!)。
是否有可能通过一些更改来维持当前结构?
表tr创建:
<tr ng-repeat="docs in itemsData | filter: searchText | filter: filterTable(currentFilter) : true | orderBy: orderType" ng-class="{'notinstock':docs.NotInStock,'text-center': true, 'marked': docs.OpenQty==docs.scanned}" ng-show="( (multipleDocs==docs.isMultiple) || (multipleDocs=='all') ) && ((docs.Docbal>0)!=noDebt) && ((docs.PartOfNotInStock>0)!=notInStock) && ((docs.FastOrder==0) != fastOrder)" docnum="{{docs.Docnum}}" orderNumber="{{docs.OrderNumber}}" barcode="{{docs.Barcode}}">
<td>
<div class="copyDiv" ng-show="(!docs.FastOrder)">
<i ng-click="searchItems(docs.Docnum, 'doc')" title="לחיצה לחיפוש / חזרה מחיפוש" ng-class="{'fa fa-search-minus': searchOnDoc==true, 'fa fa-search-plus':searchOnDoc==false}" class="searchIcon itemClick" aria-hidden="true"></i>
<span title="לחיצה להעתקה" ng-click="clipboardCopyDoc('doc'+$index)" id="copyClickDoc{{'doc'+$index}}" class="clipboard itemClick" ngclipboard data-clipboard-text="{{docs.Docnum}}"> {{docs.Docnum}}</span>
</div>
<div class="docDate" ng-show="(!docs.FastOrder)">{{docs.Docdate}}</div>
<span ng-switch on="docs.shipping" ng-click="openInvoice(docs.Docnum)" title="{{ docs.FastOrder ? '' : 'לחיצה לצפייה בפרטי חשבונית' }}" ng-class="{'itemClick' : !docs.FastOrder}">
<span ng-switch-when="shipping" class="label label-by">Chita</span>
<span ng-switch-when="shipping_ev" class="label label-purplew">Buzzr</span>
<span ng-switch-when="pickup" class="label label-bw">איסוף</span>
<span ng-switch-when="boxit" class="label label-pinkw">Boxit</span>
<span ng-switch-when="postil" class="label label-rw">דואר</span>
<span ng-switch-default class="label label-brownw">לא צוין</span>
</span>
<span ng-show="docs.FastOrder" ng-click="cancelFastOrderSure(docs.OrderNumber)" class="label label-danger itemClick cancelOrderBt" title="לחיצה לביטול ההזמנה המהירה"><i class="fa fa-fast-backward"></i> לחץ כדי להחזיר למכירות</span>
</td>
<td>
<div class="copyDiv">
<i ng-click="searchItems(docs.OrderNumber, 'doc')" title="לחיצה לחיפוש / חזרה מחיפוש" ng-class="{'fa fa-search-minus': searchOnDoc==true, 'fa fa-search-plus':searchOnDoc==false}" class="searchIcon itemClick" aria-hidden="true"></i>
<span title="לחיצה להעתקה" ng-click="clipboardCopyDoc('ord'+$index)" id="copyClickDoc{{'ord'+$index}}" class="clipboard itemClick" ngclipboard data-clipboard-text="{{docs.OrderNumber}}"> {{docs.OrderNumber}}</span>
</div>
<div class="docDate" ng-show="(docs.FastOrder)">{{docs.Docdate}}</div>
<span class="itemClick" ng-click="openOrder(docs.OrderNumber)" title="לחיצה לצפייה בפרטי ההזמנה">
<span ng-show="docs.FastOrder" class="label label-danger"><i class="fa fa-fast-backward"></i> הזמנה מהירה</span>
<span ng-show="!docs.FastOrder" class="label label-default">הזמנה רגילה</span>
</span>
</td>
<td>
<div class="copyDiv">
<i ng-click="searchItems(docs.Barcode, 'bar')" title="לחיצה לחיפוש / חזרה מחיפוש" ng-class="{'fa fa-search-minus': searchOnBar ==true, 'fa fa-search-plus':searchOnBar ==false}" class="searchIcon itemClick" aria-hidden="true"></i>
<span title="לחיצה להעתקה" ng-click="clipboardCopyBar($index)" id = "copyClickBar{{$index}}"class = "clipboard itemClick" ngclipboard data-clipboard-text="{{docs.Barcode}}"> {{docs.Barcode}}</span>
</div>
</td>
<td ng-bind-html="renderDoc(docs)"></td>
<td class="itemClick" title="לחיצה להצגת סיריאלים זמינים" ng-click="peekAtSerials(docs.Barcode,docs.Docnum,docs.OrderNumber)">{{docs.scanned}}/{{docs.OpenQty}}</td>
<td class="notes" ng-bind-html="renderHtml(docs.Notes)"></td>
<td>{{docs.cntOrdersToDemand}}/{{docs.relevantStock}}</td>
<td>{{ getShelf(docs); }}</td>
<td class="balance" ng-bind-html="renderHtml(getBal(docs.Docbal))"></td>
</tr>
该程序还需要在平板电脑上运行,因此这种使用如此多的计算问题为客户带来负担的架构 - 使用如此多的内存和资源 - 让我想知道是否需要将应用程序更改为完全基于服务器端。
我已经尝试过只使用JavaScript创建表,然后编译它。它将观察者减少到1600,但它占用了大量的内存和CPU,每次刷新表时,程序都会卡住几秒钟。这也意味着每个过滤器都需要再次创建。有更好的方法吗?
我做了什么:
HTML:
<tbody id="tBody" compile="tr" ng-show="trNow"></tbody>
<tbody id="tBody" compile="tr2" ng-show="!trNow"></tbody>
编译指令:
myApp.directive('compile', ['$compile', function ($compile) {
return function(scope, element, attrs) {
scope.$watch(
function(scope) {
return scope.$eval(attrs.compile);
},
function(value) {
element.html(value);
$compile(element.contents())(scope);
}
);
};
}]);
创建表的函数:
function makeTable(){
makeTr(function(tr){
switch($scope.trNow){
case true: //tr
$scope.tr2 = tr;
$scope.trNow = false;
$scope.tr = "";
break;
case false: //tr2
$scope.tr = tr;
$scope.trNow = true;
$scope.tr2 = "";
break;
}
}
);
}
async function makeTr(callBack){
var tr = "";
for (var i=0; i<itemsDataView.length; i++){
var titleText= itemsDataView[i].FastOrder ? '' : 'לחיצה לצפייה בפרטי חשבונית';
var trClassNIS = itemsDataView[i].NotInStock ? 'notinstock' : '';
var trClassMark = (itemsDataView[i].OpenQty == itemsDataView[i].scanned) ? 'marked' : '';
var trClass = itemsDataView[i].NotInStock ? 'notinstock' : '';
var trClass = itemsDataView[i].NotInStock ? 'notinstock' : '';
var trClass = itemsDataView[i].NotInStock ? 'notinstock' : '';
var showSearch = $scope.searchOnDoc==true ? 'fa fa-search-minus' : 'fa fa-search-plus';
var showNoFast = !itemsDataView[i].FastOrder ? '<div class="copyDiv">'+
'<i ng-click="searchItems('+itemsDataView[i].Docnum+',\'doc\')" title="לחיצה לחיפוש / חזרה מחיפוש" class="'+showSearch+' searchIcon itemClick" aria-hidden="true"></i>'+
'<span title="לחיצה להעתקה" ng-click="clipboardCopyDoc(\'doc\'+'+i+')" id="copyClickDodoc'+i+'" class="clipboard itemClick" ngclipboard data-clipboard-text="'+ itemsDataView[i].Docnum+'"> '+itemsDataView[i].Docnum+'</span>'+
'</div><div class="docDate">'+itemsDataView[i].Docdate+'</div>' : '';
var switchShippingClass = !itemsDataView[i].FastOrder ? 'itemClick' : '';
var switchShipping;
switch(itemsDataView[i].shipping){
case "shipping":
switchShipping = '<span class="label label-by">Chita</span>';
break;
case "shipping_ev":
switchShipping = '<span class="label label-purplew">Buzzr</span>';
break;
case "pickup":
switchShipping ='<span class="label label-bw">איסוף</span>';
break;
case "boxit":
switchShipping ='<span class="label label-pinkw">Boxit</span>';
break;
case "postil":
switchShipping ='<span class="label label-rw">דואר</span>';
break;
default:
switchShipping ='<span class="label label-brownw">לא צוין</span>';
}
var fastOrderSpan = itemsDataView[i].FastOrder ? '<br><span ng-click="cancelFastOrderSure('+itemsDataView[i].OrderNumber+')" class="label label-danger itemClick cancelOrderBt" title="לחיצה לביטול ההזמנה המהירה"><i class="fa fa-fast-backward"></i> לחץ לביטול הזמנה מהירה</span>' : "";
var fastOrderDiv = itemsDataView[i].FastOrder ? '<div class="docDate">'+itemsDataView[i].Docdate+'</div>' : "";
var fastOrdeSpanYesNo = itemsDataView[i].FastOrder ? '<span class="label label-danger"><i class="fa fa-fast-backward"></i> הזמנה מהירה</span>' : '<span class="label label-default">הזמנה רגילה</span>';
tr+='<tr class="'+trClassNIS +' text-center '+trClassMark+'" docnum="'+ itemsDataView[i].Docnum+'" orderNumber="'+ itemsDataView[i].OrderNumber+' "barcode="'+ itemsDataView[i].Barcode+'">'+
'<td>'+showNoFast+
'<span ng-click="openInvoice('+itemsDataView[i].Docnum+')" title="'+ titleText +'" class="'+switchShippingClass+'">'+
switchShipping+
'</span>'+
fastOrderSpan+
'</td>'+
'<td>'+
'<div class="copyDiv">'+
'<i ng-click="searchItems('+itemsDataView[i].OrderNumber+', \'doc\')" title="לחיצה לחיפוש / חזרה מחיפוש" class="'+showSearch+' searchIcon itemClick" aria-hidden="true"></i> '+
'<span title="לחיצה להעתקה" ng-click="clipboardCopyDoc(\'ord\'+'+i+')" id="copyClickDocord'+i+'" class="clipboard itemClick" ngclipboard data-clipboard-text="'+itemsDataView[i].OrderNumber+'"> '+itemsDataView[i].OrderNumber+'</span>'+
'</div>'+
fastOrderDiv+
'<span class="itemClick" ng-click="openOrder('+itemsDataView[i].OrderNumber+')" title="לחיצה לצפייה בפרטי ההזמנה">'+
fastOrdeSpanYesNo+
'</span>'+
'</td>'+
'<td>'+
'<div class="copyDiv">'+
'<i ng-click="searchItems('+itemsDataView[i].Barcode+', \'bar\')" title="לחיצה לחיפוש / חזרה מחיפוש" class="'+showSearch+' searchIcon itemClick" aria-hidden="true"></i> '+
'<span title="לחיצה להעתקה" ng-click="clipboardCopyBar('+i+')" id = "copyClickBar{{'+i+'}}" class = "clipboard itemClick" ngclipboard data-clipboard-text="'+itemsDataView[i].Barcode+'"> '+itemsDataView[i].Barcode+'</span>'+
'</div>'+
'</td>'+
'<td>'+$scope.renderDoc(itemsDataView[i])+'</td>'+
'<td class="itemClick" title="לחיצה להצגת סיריאלים זמינים" ng-click="peekAtSerials('+itemsDataView[i].Barcode+', '+itemsDataView[i].Docnum+','+itemsDataView[i].OrderNumber+')">'+itemsDataView[i].scanned+'/'+itemsDataView[i].OpenQty+'</td>'+
'<td class="notes">'+$scope.renderHtml(itemsDataView[i].Notes)+'</td>'+
'<td>'+itemsDataView[i].cntOrdersToDemand+'/'+ itemsDataView[i].relevantStock+'</td>'+
'<td>'+$scope.getShelf(itemsDataView[i])+'</td>'+
'<td class="balance">'+$scope.renderHtml($scope.getBal(itemsDataView[i].Docbal))+'</td>'+
'</tr>';
}
callBack (tr);
}