使用 DurandalJS,我创建了一个显示特定数据的 web 应用程序。这些数据是通过 BreezeJS 收集的,并从 durandalJS 框架的激活函数中调用。
当我第一次进入页面 A 时,所有数据都已正确加载。然后,当我使用页面 A 上的链接转到页面 B,然后使用链接从页面 B 回到 A 时,我可以看到数据已加载到我的 knockoutJS observablearrays 中,但未显示!
当页面上有多个可观察数组(例如 A1、B2 和 C3)在第一次加载时,当我在 Web 应用程序上冲浪并返回带有可观察数组的特定页面时,它们都已正确加载,而 A1 和 C3 已加载而 B2 未加载!另一个力矩 A1 和 B2 和 C3 未显示。一切都很随意!
当我按 CTRL + F5 时,一切都已正确加载。这和 DurandalJS 的框架有关系吗?有谁知道如何解决这个问题?
到目前为止我尝试了什么:使用延迟使用停用,以便以正确的方式清理属性,以便可以填写激活
到目前为止什么都没有
图书馆的版本:
- 淘汰赛JS:2.3.0
- 微风JS:1.4.0
- 杜兰达尔JS:1.2.0
这些是我包含的图书馆的当前版本。他们最近更新了,希望这能解决问题,但没有。
这是我的单例数据服务:
var DataserviceClass = (function () {
function DataserviceClass() {
this._isSaving = false;
this.suspendItemSave = false;
this.ds = new breeze.DataService({
serviceName: "api/data",
hasServerMetadata: true
});
this.manager = new breeze.EntityManager({dataService: this.ds});
this.metadataStore = this.manager.metadataStore;
this.entityQuery = new breeze.EntityQuery();
this.getMetadataStore = function () {
return this.metadataStore;
};
this.getExportData = function() {
return this.manager.exportEntities();
};
this.getAllRows = function (functionName, expand) {
if (expand == null || expand == undefined) {
this.entityQuery = breeze.EntityQuery.from(functionName);
} else {
this.entityQuery = breeze.EntityQuery.from(functionName).
expand(expand);
}
return this.manager.executeQuery(this.entityQuery);
};
this.getSpecificID = function (functionName, idName, id) {
this.entityQuery = breeze.EntityQuery.from(functionName).where(idName, "==", id);
return this.manager.executeQuery(this.entityQuery);
};
this.createT = function (initialValues, entity) {
return this.manager.createEntity(entity, initialValues);
};
this.saveChanges = function (suppressLogIfNothingToSave) {
if (this.manager.hasChanges()) {
if (this._isSaving) {
setTimeout(this.saveChanges, 50);
return;
}
return this.manager.saveChanges().then(this.saveSucceeded).fail(this.saveFailed).fin(this.saveFinished);
} else if (!suppressLogIfNothingToSave) {
}
};
this.saveSucceeded = function (saveResult) {
this._isSaving = false;
};
this.saveFailed = function (error) {
};
this.saveFinished = function () {
this._isSaving = false;
};
}
var instance;
return {
getInstance: function() {
if (instance == null) {
instance = new DataserviceClass();
instance.constructor = null;
}
return instance;
}
};
})();
在像估计这样的页面上,它被称为如下,这是视图模型:
define(function (require) {
var router = require('durandal/plugins/router'),
app = require('durandal/app'),
system = require('durandal/system'),
addmemo = require('viewmodels/modals/addMemo'),
container = require('viewmodels/modals/container'),
memo = require('viewmodels/modals/memo'),
dataservice = require('services/dataservice'),
logger = require('services/logger'),
addRepairOrderLine = require('viewmodels/modals/addRepairOrderLine'),
repairorderline = require('viewmodels/modals/RepairOrderLine'),
customerModal = require('viewmodels/modals/customer'),
currentLoggedInEmployee = ko.observable(),
memos = ko.observableArray([]),
deferred = $.Deferred(),
repairorderlines = ko.observableArray([]),
tasksToMonitor = [],
isLoading = ko.observable(false),
suspendItemSave = false,
rightParameters = true,
notDone = true,
hourscost = ko.observable(0.0),
materialcost = ko.observable(0.0),
grandtotal = ko.observable(0.0),
currentRepairOrderID = -1,
currentOrderID = -1,
currentOrder = ko.observable(),
currentRepairOrder = ko.observable(null),
currentContainerID = -1,
currentCustomer = ko.observable(null),
currentBillingCustomer = ko.observable(null),
currentContainer = ko.observable(null),
showElementFade = function(elem) { if (elem.nodeType === 1) $(elem).hide().slideDown(); },
hideElementFade = function(elem) { if (elem.nodeType === 1) $(elem).slideUp(function() { $(elem).remove(); }); };
//This function is called ones, only when the page hasn't loaded yet!
function init() {
dataservice = DataserviceClass.getInstance();
dataservice.getSpecificID('Employees', 'EmployeeID', 1).then(function (data) {
currentLoggedInEmployee = data.results[0];
}).fail(function(data) {
logger.logError('Error fetching the current logged in employee!', null, null, true);
});
}
init();
return {
displayName: 'Estimating page',
router: router,
currentCustomer: currentCustomer,
currentContainer: currentContainer,
currentRepairOrder: currentRepairOrder,
currentBillingCustomer: currentBillingCustomer,
memos: memos,
repairorderlines: repairorderlines,
isLoading: isLoading,
hourscost: hourscost,
materialcost: materialcost,
grandtotal: grandtotal,
activate: function (Context) {
currentRepairOrder(null);
currentBillingCustomer(null);
rightParameters = true;
//also need to check if ids exist in DB!!
if (!Context.hasOwnProperty("orderid") || isNaN(Context.orderid) ||
!Context.hasOwnProperty("repairorderid") || isNaN(Context.repairorderid)) {
rightParameters = false;
system.log('Not all the right parameters!');
router.navigateTo('#/error'); //eventueel parameters meegeven!
return;
}
//set id's
currentRepairOrderID = Context.repairorderid;
currentOrderID = Context.orderid;
tasksToMonitor = []; //empty the task function
breeze.EntityQuery.from("Orders")
.where("OrderID", "==", parseInt(Context.orderid))
.expand("Customer, Customer.PostCountry, Customer.VisitCountry, Container, Container.ContainerManufacturer, Container.ContainerType, Container.Owner")
.using(dataservice.manager)
.execute().then(function (data) {
if (data.results.length < 1) {
system.log('Not all the right parameters!');
rightParameters = false;
router.navigateTo('#/error'); //eventueel parameters meegeven!
return;
}
//extendItem(data.results[0]);
currentOrder(data.results[0]);
var customer = data.results[0].Customer();
//extendItem(customer);
currentCustomer(customer);
var container = data.results[0].Container();
//extendItem(container);
currentContainer(container);
}).fail(function (data) {
logger.logError('Error fetching the current Order!', null, null, true);
}).fin(function() {
});
//In the future this will be calling the order 2
breeze.EntityQuery.from("RepairOrders")
.where("RepairOrderID", "==", parseInt(Context.repairorderid))
.expand("BillingCustomer, BillingCustomer.PostCountry, BillingCustomer.VisitCountry")
.using(dataservice.manager)
.execute().then(function (data) {
currentRepairOrder(data.results[0]);
currentBillingCustomer(data.results[0].BillingCustomer());
}).fail(function (data) {
logger.logError('Error fetching current repairorder!', null, null, true);
}).fin(function() {
//first set the value to true (loading done)
//Call the global function to check each process
tasksToMonitor[0][1] = true;
checkTasks();
});
//by adding this if statements the data is only loaded if it hasn't been loaded yet!
//voor nu alle memos van alle medewerkers, later alleen die van betreffende?
if (memos._latestValue.length == 0) {
breeze.EntityQuery.from("Memos")
.where("RepairOrderID", "==", parseInt(Context.repairorderid))
//.expand("Customer, Container, Container.ContainerManufacturer, Container.ContainerType")
.expand("Employee")
.using(dataservice.manager)
.execute().then(function (data) {
data.results.forEach(function (item) {
extendItem(item);
memos.push(new memo(item));
});
system.log("Initialization succesfull!");
logger.logSuccess('Initialization succesfull', null, 'estimatepage', true);
}).fail(function (data) {
logger.logError('Error fetching memos!', null, null, true);
}).fin(function() {
tasksToMonitor[1][1] = true;
checkTasks();
});
}
if (repairorderlines._latestValue.length == 0) {
breeze.EntityQuery.from("RepairOrderLines")
.where("RepairOrderID", "==", parseInt(Context.repairorderid))
.expand("Customer")
.using(dataservice.manager)
.execute().then(function (data) {
data.results.forEach(function (item) {
extendItem(item);
repairorderlines.push(new repairorderline(item));
});
updateFinance();
//
}).fail(function (data) {
logger.logError('Error fetching repairorderlines!', null, null, true);
}).fin(function() {
tasksToMonitor[2][1] = true;
checkTasks();
// deferred.resolve();
});
}
logger.log("Estimating page started!", null, "estimagepage", true);
return deferred.promise();
//return;
},
canDeactivate: function () {
if (rightParameters && notDone) {
return app.showMessage('Are you sure you want to leave this page and stop estimating?', 'Navigate', ['Yes', 'No']);
} else {
return true;
}
},
deactivate: function() {
//remove everything here! I mean remove the data in the models! Everything is already saved ;)
memos.removeAll();
repairorderlines.removeAll();
currentRepairOrderID = -1;
currentOrderID = -1;
currentOrder(null);
currentRepairOrder(null);
currentContainerID = -1;
currentCustomer(null);
currentBillingCustomer(null);
currentContainer(null);
},
showCustomerModal: function(selectedCustomer,element) {
app.showModal(new customerModal(selectedCustomer)).then(function () {
}).fail(function() {
});
},
showContainerModal: function() {
app.showModal(new container(currentContainer, currentOrder())).then(function (result) {
}).fail(function(result) {
});
},
cancelEstimation: function() {
app.showMessage('Do you want to delete this estimation?', 'Delete estimate', ['Yes', 'No']).then(function (resultMessageBox) {
if (resultMessageBox == "Yes") {
}
//else if no the user just clicked OK and everything is saved
});
},
selectedRepairOrderLine: function (selectedRepairOrderLine, element) {
app.showModal(selectedRepairOrderLine).then(function (result) {
if (result) {
app.showMessage('Do you want to delete this RepairOrderLine?', 'Delete RepairOrderLine', ['Yes', 'No']).then(function (resultMessageBox) {
if (resultMessageBox == "Yes") {
repairorderlines.remove(selectedRepairOrderLine);
selectedRepairOrderLine.RepairOrderLineEntity._latestValue.entityAspect.setDeleted();
dataservice.saveChanges();
updateFinance(); //dont remove this one its called !
logger.logSuccess('Repairline deleted successfully', null, null, true);
}
//else if, no the user just clicked OK and everything is saved so also updatefinance is called a couple of line further
});
}
updateFinance(); //But we must update the finance because things could have been changed!
}).fail(function () {
logger.logError('Something went wrong selecting the memo!', null, 'estimatepage', true);
});
},
selectedMemo: function (selectedMemo, element) {
app.showMessage('Do you want to delete this memo?', 'Delete memo', ['Yes', 'No']).then(function (resultMessageBox) {
if (resultMessageBox == "Yes") {
memos.remove(selectedMemo);
selectedMemo.MemoEntity._latestValue.entityAspect.setDeleted();
dataservice.saveChanges();
}
//else if no the user just clicked OK and everything is saved
}).fail(function () {
logger.logError('Something went wrong selecting the memo!', null, 'estimatepage', true);
});
},
};
});
这是它附带的视图:
<div class="row-fluid">
<div class="span6">
<!-- Estimate Information -->
<!-- Estimate HEADER -->
<div class="fiftypx" data-bind='with: currentContainer'>
<span class="main_title">ESTIMATE</span>
<span class="main_container_number" data-bind="text: ContainerNumber"></span>
</div>
<!-- Estimate Propertys -->
<div class="row-fluid">
<div class="span6">
<fieldset>
<div class="estimate_info" data-bind="with: currentContainer">
<span class="estimatepage_info_text">container number</span>
<div data-bind="" class="estimate_info_DIV">
<span data-bind="text: ContainerNumber"></span>
</div>
</div>
<div style="clear: both;"></div>
<div class="estimate_info" data-bind="with: currentBillingCustomer">
<span class="estimatepage_info_text">billing customer</span>
<div data-bind="click: $parent.showCustomerModal" class="estimate_info_DIV">
<span data-bind="text: Name"></span>
</div>
<button class="flatButtonSmall" data-bind="click: $parent.showCustomerModal">›</button>
</div>
<div style="clear: both;"></div>
<div class="estimate_info" data-bind='with: currentContainer'>
<span class="estimatepage_info_text">equipment</span>
<div data-bind="click: $parent.showContainerModal" class="estimate_info_DIV">
<span data-bind="text: ContainerNumber"></span>
</div>
<button class="flatButtonSmall" data-bind="click: $parent.showContainerModal">›</button>
</div>
<div style="clear: both;"></div>
</fieldset>
</div>
<div class="span6">
<fieldset>
<!--<legend></legend> Deze niet toevoegen uitlijning is dan niet goed!-->
<div class="estimate_info" data-bind="with: currentRepairOrder">
<span class="estimatepage_info_text">repair order</span>
<div class="estimate_info_DIV">
<span data-bind="text: RepairOrderID"></span>
</div>
</div>
<div style="clear: both;"></div>
<div class="estimate_info" data-bind='with: currentCustomer'>
<span class="estimatepage_info_text">relation</span>
<div data-bind="click: $parent.showCustomerModal" class="estimate_info_DIV">
<span data-bind="text: Name"></span>
</div>
<button class="flatButtonSmall" data-bind="click: $parent.showCustomerModal">›</button>
</div>
<div style="clear: both;"></div>
<div class="estimate_info" data-bind="with: currentRepairOrder">
<span class="estimatepage_info_text">creation date</span>
<div class="estimate_info_DIV">
<span data-bind="text: Created().getDate() + '-' + (Created().getMonth() + 1) + '-' + Created().getFullYear()"></span>
</div>
</div>
<div style="clear: both;"></div>
</fieldset>
</div>
</div>
</div>
<div class="span6">
<!-- Memo's -->
<div class="fiftypx">
<span class="main_title">MEMO'S</span>
<button class="newButton" data-bind="click: addMemo">NEW</button>
<button data-bind="click: doneEstimating" style="width: 130px;float: right;margin-right: 25px;" class="flatButtonBig" data-bind="">DONE</button>
<div style="clear: both;"></div>
<div>
<div class="loader" data-bind="css: { active: isLoading }">
<i class="icon-spinner icon-2x icon-spin"></i>
</div>
</div>
</div>
<div id="memosTable">
<table class="table" style="margin-left: -25px;">
<thead>
<tr>
<th></th><th>date / user</th><th>memo</th><th></th>
</tr>
</thead>
<tbody data-bind="visible: memos().length > 0, foreach: memos">
<tr class="rowStyleFront">
<td style="width:25px;"></td>
<td style="width: 115px;">
<!-- date and user -->
<!-- text: MemoEntity._latestValue.CreationDate -->
<span class="upperSpan" data-bind="">Datum</span>
<div style="clear: both;"></div>
<span class="lowerSpan" data-bind="text: MemoEntity._latestValue.Employee().Username()"></span>
</td>
<td style="width: 300px;">
<!-- memo -->
<span style="display: inline; background-color: #f4931D; color: #FFFFFF; padding-right: 7px; padding-left: 5px;" class="upperSpan" data-bind="textToUpperCase: MemoEntity._latestValue.Type"></span>
<div style="clear: both;"></div>
<span style="margin-top: 20px; width: inherit;" class="lowerSpan" data-bind="text: MemoEntity._latestValue.Description"></span>
</td>
<td style="width: 50px;"><button data-bind="click: $parent.selectedMemo" style="float: right;" class="flatButtonBig" data-bind="">X</button></td>
</tr>
</tbody>
<tbody data-bind="visible: memos().length == 0">
<tr class="rowStyleFront">
<td style="width:25px;"></td>
<td colspan="3">You haven't made any memo's yet.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="row-fluid">
<div class="span6">
<!-- Add new repairline button and text -->
<div class="fiftypx">
<span class="main_title">REPAIRLINES</span>
<button class="newButton" data-bind="click: addRepairline">NEW</button>
</div>
</div>
<div class="span6" style="line-height: 50px;">
<!-- totals! -->
<div class="row-fluid">
<div class="span4">Hours cost: <span style="font-size: 16px;" data-bind="text: hourscost()"></span></div>
<div class="span4">Materials: <span style="font-size: 16px;" data-bind="text: materialcost()"></span></div>
<div class="span4">Total: <span style="font-size: 16px;" data-bind="text: grandtotal()"></span></div>
</div>
</div>
</div>
<div class="row-fluid">
<div class="span12">
<!-- Table with all repairlines -->
<table class="table" style="margin-left: -25px;">
<thead>
<tr>
<th></th>
<th>Description</th>
<th></th>
<th>Code</th>
<th>Mat</th>
<th>LOC</th>
<th>Rep</th>
<th>DAM</th>
<th>Customer</th>
<th>IsAgreement</th>
<th>Qty</th>
<th>Hours</th>
<th>Tariff</th>
<th>Costs</th>
<th>Lessee</th>
<th>Authorized</th>
<th>DoRepair</th>
<th><!-- Button --></th> <!-- 17 rijen -->
</tr>
</thead>
<tbody data-bind="visible: repairorderlines().length > 0, foreach: repairorderlines">
<tr class="rowStyleFront">
<td style="width:25px;"></td>
<td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.Description"></td>
<td></td>
<td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.InternalCode"></td>
<td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.MaterialCode"></td>
<td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.LocationCode"></td>
<td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.RepairCode"></td>
<td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.DamageCode"></td>
<td style="text-align: left;" data-bind="click: $parent.selectedRepairOrderLine, text: RepairOrderLineEntity._latestValue.Customer().Name()"></td>
<td><input type="checkbox" data-bind="checked: RepairOrderLineEntity._latestValue.IsAgreement"/></td>
<td data-bind="click: $parent.selectedRepairOrderLine, numericText: RepairOrderLineEntity._latestValue.Quantity"></td>
<td data-bind="click: $parent.selectedRepairOrderLine, numericText: RepairOrderLineEntity._latestValue.Hours"></td>
<td data-bind="click: $parent.selectedRepairOrderLine, numericText: RepairOrderLineEntity._latestValue.Tariff"></td>
<td data-bind="click: $parent.selectedRepairOrderLine, numericText: RepairOrderLineEntity._latestValue.Costs"></td>
<td data-bind="click: $parent.selectedRepairOrderLine">-</td>
<td><input type="checkbox" data-bind="checked: RepairOrderLineEntity._latestValue.IsAuthorized"/></td>
<td><input type="checkbox" data-bind="checked: RepairOrderLineEntity._latestValue.DoRepair"/></td>
<td style="width: 50px;"><button class="flatButtonBig" data-bind="click: $parent.selectedRepairOrderLine">›</button></td>
</tr>
</tbody>
<tbody data-bind="visible: repairorderlines().length == 0">
<tr class="rowStyleFront">
<td style="width:25px;"></td>
<td colspan="16">You haven't made any repairlines yet.</td>
</tr>
</tbody>
</table>
</div>
</div>
格。乐华