[英]Knockout - Binding to reference object
我有一個淘汰賽應用程序,其中“估計”是頁面的主要對象。 該估計包含一個ObservableArray of WorkOrder對象(WorkOrdersDTO),但是一次僅顯示一個WorkOrder對象進行編輯。 用戶可以通過從選擇列表中進行選擇來選擇顯示要編輯的WorkOrder。 我遇到的問題是我正在使用名為CurrentWorkOrder的對象來引用當前正在編輯的WorkOrder。 設置此對象時,我遇到了一些性能問題。 估計包含的工作訂單越多,這些性能問題就越嚴重。 當用戶添加WorkOrder時會出現最大的問題。 這是該過程的代碼:
self.addWorkOrder = function () {
tempWOId += 1;
var workOrder = new WorkOrder();
workOrder.WorkOrderId(tempWOId);
workOrder.WorkOrderNo(self.SetWorkOrderNo());
self.estimate().WorkOrdersDTO.push(workOrder);
self.estimate().CurrentWorkOrder($.grep(self.estimate().WorkOrdersDTO(), function (wo) { return wo == workOrder })[0]);
};
該功能的最后一行是花費最多時間的那一行。 我也嘗試過使用它,但是它甚至更慢。
self.estimate().CurrentWorkOrder(self.estimate().WorkOrdersDTO()[self.estimate().WorkOrdersDTO().length - 1]);
我還在我的html中取出了“ with”綁定,但是沒有看到任何結果。 我什至注釋掉了整個html,其中進行了綁定,以確保不是由性能引起的性能問題,並且性能沒有變化。
有任何想法嗎?
我回過頭來以幾種不同的方式為該行代碼計時,結果如下:CurrentWorkOrder($。grep)-613.000ms
CurrentWorkOrder(WorkOrdersDTO.length)-740.000ms
CurrentWorkOrder(workOrder)-689.000毫秒
不帶html引用的CurrentWorkOrder($。grep)-317.000ms
刪除綁定到CurrentWorkOrder的HTML時,性能會更好,這使我相信這是其中的一部分。 這是該部分的完整HTML:
<div id="work-order-details">
<div class="work-order-details" data-bind='with: estimate' style="margin-bottom:5px;">
<table style="width:100%">
<tr>
<td>
<table>
<tr>
<td style="text-align:right;">
Group
</td>
<td>
<select class="k-input" data-bind='options: WorkOrderGroupsDTO, value: CurrentWorkOrder().WorkOrderGroupId, optionsValue: "WorkOrderGroupId", optionsText: "GroupName", optionsCaption: "--Select--"'></select>
</td>
<td>
<span id="AddWorkOrderGroupButton"><span class="icon-add" data-bind='click: $root.addWorkOrderGroup'></span>
</td>
<td>
Service Date
</td>
<td>
<input style="width:120px;" id='service-date' data-bind="value: CurrentWorkOrder().ServiceDateDisplay" />
</td>
</tr>
</table>
</td>
<td style="text-align:right;">
Additional Work Orders <select id='workOrderSelect' class="k-input num-textbox" data-bind="options: WorkOrdersDTO, optionsValue: 'WorkOrderId', optionsText: 'WorkOrderNo'"></select>
</td>
</tr>
</table>
</div>
<div class="work-order-details" data-bind='with: estimate'>
<table class="table-container" style="border:solid 1px darkgray;">
<tr>
<th class="table-cell-2 estimate-wo-header" colspan="2">INSTRUCTIONS</th>
</tr>
<tr class="table-row">
<td colspan='2'>
<textarea class="textarea" name="" id="estimate-textarea" rows="4" data-bind='value: CurrentWorkOrder().Instructions' placeholder='Enter Instructions...'></textarea>
</td>
</tr>
<tr>
<th class="table-cell-2 estimate-wo-header labor-tasks">LABOR INFORMATION
<a href="#" data-bind='click: $root.addWorkOrderLaborTask'>Add</a>
</th>
<th class="table-cell-2 estimate-wo-header packing-materials">PACKING MATERIALS<a href="#" data-bind='click: $root.addWorkOrderPackingMaterial'>Add</a></th>
</tr>
<tr class="table-row">
<td class="table-cell-3 labor-tasks" style="border:solid 1px darkgray;padding-left:10px;padding-bottom:10px;">
<table class="estimate-table">
<tr class="header-row">
<td>Task</td>
<td>Qty</td>
<td>Hours</td>
<td>RT Rate</td>
<td>OT Rate</td>
<td>PT Rate</td>
<td>Cost</td>
</tr>
<tbody class='table-body' data-bind="foreach: CurrentWorkOrder().WorkOrderLaborTasksDTO">
<tr>
<td>
<select class="k-input smaller-textbox" data-bind='options: LaborTaskData, value: LaborTaskId, optionsValue: "LaborTaskId", optionsText: "Task", optionsCaption: "--Select--"'/>
</td>
<td>
<input type="number" min='0' class="k-textbox num-textbox" style="width:40px;" data-bind='value: Quantity' onkeypress="return numeric_only(event)" />
</td>
<td>
<input type="number" min='0' class="k-textbox num-textbox" data-bind='value: TotalHours' onkeypress="return numeric_only(event)" />
</td>
<td>
$0.00
</td>
<td>
$0.00
</td>
<td>
$0.00
</td>
<td>
<span data-bind='text: TotalCostDisplay'></span>
</td>
<td>
<a href='#' data-bind='click: $root.removeWorkOrderLaborTask'>X</a>
</td>
</tr>
</tbody>
</table>
</td>
<td class="table-cell-2 packing-materials" style="border:solid 1px darkgray;padding-left:10px;padding-bottom:10px;">
<table class="estimate-table">
<tr class="header-row">
<td>Material</td>
<td>Qty</td>
<td>Unit Price</td>
<td>Cost</td>
<td></td>
</tr>
<tbody class='table-body' data-bind="foreach: CurrentWorkOrder().WorkOrderPackingMaterialsDTO">
<tr>
<td><select style="width:275px;" class="k-input" data-bind="options: PackingMaterialData, value: MaterialId, optionsValue: 'MaterialId', optionsText: 'Description', optionsCaption: '--Select--'"></select></td>
<td><input type="number" min='0' class="k-textbox num-textbox" data-bind='value: Quantity' onkeypress="return numeric_only(event)" /></td>
<td><span data-bind='text: UnitPrice'></span></td>
<td><span data-bind='text: CostDisplay'></span></td>
<td><a href='#' data-bind='click: $root.removeWorkOrderPackingMaterial'>X</a></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<th class="table-cell-2 estimate-wo-header installation-products">INSTALLATION <a id='add-installation-product' href="#" data-bind="click: $root.addWorkOrderInstallationProduct">Add</a></th>
<th class="table-cell-2 estimate-wo-header unitized-items">UNITIZED PRICING <a id='add-installation-product' href="#" data-bind="click: $root.addWorkOrderUnitizedItem">Add</a></th>
</tr>
<tr class="table-row">
<td class="table-cell-2 installation-products" style="border:solid 1px darkgray;padding-left:10px;padding-bottom:10px;">
<table class="estimate-table">
<tr class="header-row">
<td>Manufacturer</td>
<td>Product Line</td>
<td>Cost</td>
<td></td>
</tr>
<tbody class='table-body' data-bind="foreach: CurrentWorkOrder().WorkOrderInstallationProductsDTO">
<tr>
<td hidden data-bind='text: WorkOrderInstallationProductId'></td>
<td>
<select class="k-input larger-textbox select-mfr" data-bind="options: ManufacturerData, value: ManufacturerId, optionsValue: 'ManufacturerId', optionsText: 'Name', optionsCaption: '--Select--'"></select>
</td>
<td>
<select data-bind="options: ProductLines, value: ProductId, optionsValue: 'ProductLineId', optionsText: 'Name', optionsCaption: '--Select--'" id="" class="k-input big-textbox"></select>
</td>
<td data-bind="text: CostDisplay"></td>
<td>
<a href='#' data-bind='click: $root.editWorkOrderInstallationProduct'>Edit</a>
<a href='#' data-bind='click: $root.removeWorkOrderInstallationProduct'>X</a>
</td>
</tr>
</tbody>
</table>
</td>
<td class="table-cell-2 unitized-items" style="border:solid 1px darkgray;padding-left:10px;padding-bottom:10px;">
<table class="estimate-table">
<tr class="header-row">
<td>Service</td>
<td>Qty</td>
<td>Unit Price</td>
<td>Cost</td>
<td></td>
</tr>
<tbody class='table-body' data-bind="foreach: CurrentWorkOrder().WorkOrderUnitizedItemsDTO">
<tr>
<td><select style="width:275px;" class="k-input" data-bind="options: UnitizedItemData, value: UnitId, optionsValue: 'UnitId', optionsText: 'Description', optionsCaption: '--Select--'"></select></td>
<td><input type="number" min='0' class="k-textbox num-textbox" data-bind='value: Quantity' style="width:40px;" onkeypress="return numeric_only(event)" /></td>
<td><span data-bind='text: UnitPrice'></span></td>
<td><span data-bind='text: CostDisplay'></span></td>
<td><a href='#' data-bind='click: $root.removeWorkOrderUnitizedItem'>X</a></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<th class="table-cell-2 estimate-wo-header storage">STORAGE & HANDLING <a id='add-storage' href="#" data-bind="click: $root.addWorkOrderStorage">Add</a></th>
<th class="table-cell-2 estimate-wo-header tech-services">TECH SERVICES<a href="#" data-bind='click: $root.addWorkOrderTechService'>Add</a></th>
</tr>
<tr class="table-row">
<td class="table-cell-2 storage" style="border:solid 1px darkgray;padding-left:10px;padding-bottom:10px;">
<table class="estimate-table">
<tr class="header-row">
<td>Inventory</td>
<td>Storage</td>
<td>Handling</td>
<td>Valuation</td>
<td>Cost</td>
</tr>
<tbody class='table-body' data-bind="foreach: CurrentWorkOrder().WorkOrderStoragesDTO">
<tr>
<td class="storage-cell"><span data-bind="text: InventoryTypeName"></span></td>
<td class="storage-cell"><span data-bind="text: EstimatedStorage"></span></td>
<td class="storage-cell"><span data-bind="text: HandlingIn"></span></td>
<td class="storage-cell"><span data-bind='text: ValuationTypeCharges'></span></td>
<td class="storage-cell"><span data-bind='text: EstimatedStorage'></span></td>
</tr>
</tbody>
</table>
</td>
<td class="table-cell-2 tech-services" style="border:solid 1px darkgray;padding-left:10px;padding-bottom:10px;">
<table class="estimate-table">
<tr class="header-row">
<td>Service</td>
<td>Qty</td>
<td>Unit Price</td>
<td>Cost</td>
<td></td>
</tr>
<tbody class='table-body' data-bind="foreach: CurrentWorkOrder().WorkOrderTechServicesDTO">
<tr>
<td><select style="width:275px;" class="k-input" data-bind="options: TechServiceData, value: UnitId, optionsValue: 'UnitId', optionsText: 'Description', optionsCaption: '--Select--'"></select></td>
<td><input type="number" min='0' class="k-textbox num-textbox" data-bind='value: Quantity' onkeypress="return numeric_only(event)" /></td>
<td><span data-bind='text: UnitPrice'></span></td>
<td><span data-bind='text: CostDisplay'></span></td>
<td><a href='#' data-bind='click: $root.removeWorkOrderTechService'>X</a></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<th class="table-cell-2 estimate-wo-header other-services">OTHER SERVICES <a id='add-other-service' href="#" data-bind='click: $root.addWorkOrderOtherService'>Add</a></th>
<th class="table-cell-2 estimate-wo-header third-party-services">THIRD PARTY SERVICES <a id='add-third-service' href="#" data-bind='click: $root.addWorkOrderThirdPartyService'>Add</a></th>
</tr>
<tr class='table-row'>
<td class="table-cell-2 other-services" style="border:solid 1px darkgray;padding-left:10px;padding-bottom:10px;">
<table class='estimate-table'>
<tr class="header-row">
<td>Description</td>
<td>Cost</td>
</tr>
<tbody class='table-body' data-bind="foreach: CurrentWorkOrder().WorkOrderOtherServicesDTO">
<tr>
<td><input style="width:360px;" class="k-textbox" type="text" data-bind="value: Description" /></td>
<td><input class="k-textbox smaller-textbox" data-bind='value: CostDisplay' onkeypress="return numeric_only(event)" /></td>
<td><a href='#' data-bind='click: $root.removeWorkOrderOtherService'>X</a></td>
</tr>
</tbody>
</table>
</td>
<td class="table-cell-2 third-party-services" style="border:solid 1px darkgray;padding-left:10px;padding-bottom:10px;">
<table class='estimate-table'>
<tr class="header-row">
<td>Description</td>
<td>Source</td>
<td>Src Cost</td>
<td>Cost</td>
</tr>
<tbody class='table-body' data-bind="foreach: CurrentWorkOrder().WorkOrderThirdPartyServicesDTO">
<tr>
<td><input class="k-textbox" type="text" data-bind="value: Description" /></td>
<td><input class="k-textbox smaller-textbox" type="text" data-bind="value: Source" /></td>
<td><input class="k-textbox mini-textbox" type="text" data-bind="value: SourceCost" /></td>
<td><input class="k-textbox mini-textbox" data-bind='value: CostDisplay' style="width:40px;" /></td>
<td><a href='#' data-bind='click: $root.removeWorkOrderThirdPartyService'>X</a></td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
</div>
我當時以為不使用表可以使標記的渲染速度更快,但是我一直在猶豫是否要切換它,因為這使其他開發人員更加滿意。
您的最后一行實際上只是一種復雜且耗時的操作
self.estimate().CurrentWorkOrder(workOrder);
由於workOrder
是使用構造函數實例化的,因此它將是數據中唯一可以與自身進行比較的對象,因此無需搜索它。
通過對addWorkOrder函數進行一些小的更改,我能夠大大加快該過程。
self.addWorkOrder = function () {
tempWOId += 1;
self.estimate().CurrentWorkOrder(new WorkOrder());
self.estimate().CurrentWorkOrder().WorkOrderId(tempWOId);
self.estimate().CurrentWorkOrder().WorkOrderNo(self.SetWorkOrderNo());
self.estimate().WorkOrdersDTO.push(self.estimate().CurrentWorkOrder());
};
而不是每次都將workOrder實例化為其自己的變量,而只是將CurrentWorkOrder設置為新的WorkOrder並直接設置其屬性。 這使其速度提高了約8倍,應該可以接受。
感謝您的幫助和建議。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.