I have been struggling with this problem for a very long time and think why not ask about it here on Stackoverflow! My question is this:
I am creating a single page application (SPA) with Durandal and BreezeJS. Whenever the user creates something new, the createEntity function from Breeze Lib is called and I return my object. I insert this in Ko.observablearray and voila, it works fine;)
Before that, everything works fine.
But now the hard part comes in, I use ko.observablearray to create a data-bound table. Each line is clickable, and when you click on it, the SelectedMemo function is called and the "element" completes successfully. But here, when this function needs to create a custom modal, nothing happens. I get the error /app/views/.html does not exist. I know what is happening here, it is trying to redirect to a nonexistent page, because there is no View and model-view of the created object.
How to fix this problem? SO, that when I click a row in my table, I see all the data of my element?
This is the code so far:
VIew Model:
define(function (require) { var router = require('durandal/plugins/router'), app = require('durandal/app'), system = require('durandal/system'), addmemo = require('viewmodels/modals/addMemo'), memo = require('viewmodels/modals/memo'), //probably in the models folder but for now its okay dataservice = require('services/dataservice'), memos = ko.observableArray([]), suspendItemSave = false; function extendMemo(memoToExtend) { if (memoToExtend.isEditing) return; // already extended memoToExtend.isEditing = ko.observable(false); //Deze functie wordt getriggerd zodra het aanpassen klaar is! // listen for changes with Breeze PropertyChanged event memoToExtend.entityAspect.propertyChanged.subscribe(function () { if (memoToExtend.propertyChangedPending || suspendItemSave) { return; } // throttle property changed response // allow time for other property changes (if any) to come through memoToExtend.propertyChangedPending = true; setTimeout(validateAndSaveModifiedItem, 10); function validateAndSaveModifiedItem() { if (memoToExtend.entityAspect.entityState.isModified()) { if (memoToExtend.entityAspect.validateEntity()) { dataservice.saveChanges(); } else { // errors // handleItemErrors(memoToExtend); memoToExtend.isEditing(true); // go back to editing } } memoToExtend.propertyChangedPending = false; } }); } function init() { dataservice = new dataservice('api/memo'); dataservice.getAllRows('AllMemos').then(function (data) { data.results.forEach(function (item) { //Important step otherwise you are not able to create a memo modal! extendMemo(item); // memos.push(new memo(item)); memos.push(item); }); system.log("Initialization succesfull!"); }).fail(function() { system.log("Error initialization!"); }); } init(); return { displayName: 'Estimating page', memos: memos, activate: function() { system.log("Estimating page started!"); }, canDeactivate: function() { return app.showMessage('Are you sure you want to leave this page and stop estimating?', 'Navigate', ['Yes', 'No']); }, addMemo: function() { app.showModal(new addmemo()).then(function (result) { //maby first extend? For editing on the go see hot towel if (result != undefined) { var memoN = dataservice.createT({ Description: result[0].Description, CreationDate: result[0].CreationDate, Employee: result[0].User, Type: result[0].Type }, 'tblMemo'); if (memoN.entityAspect.validateEntity()) { extendMemo(memoN); //deze //memos.push(new memo(memoN)); //& deze moeten gewrapped worden!!! anders werkt de entityAspect niet memos.push(memoN); dataservice.saveChanges(); } /* if (memoN.entityAspect.validateEntity()) { //memos.push(memoN); //this is not the right thing to add this should be a memo Object! extendMemo(memoN); // extendMemo(newMemo); memos.push(new memo(memoN.Employee(), memoN.Description(), memoN.Type(), memoN.CreationDate())); dataservice.saveChanges(); }*/ } }).fail(function(result) { //in future show nice error message, hmmm toastr....? }); }, selectedMemo: function (selectedMemo, element) { //need to make a temp object with data before user clicks okay button or what so ever. //THis because the input fields are all observables if (selectedMemo) { selectedMemo.isEditing(true); } app.showModal(selectedMemo).then(function (result) { if (result) { if (selectedMemo) { selectedMemo.isEditing(false); memos.remove(selectedMemo); selectedMemo.entityAspect.setDeleted(); dataservice.saveChanges(); } } }).fail(function() { }); //futher use for deleting memo /* app.showMessage('Do you want to delete this memo?', 'Delete memo', ['Yes', 'No']).then(function (result) { if (result == "Yes") { memos.remove(selectedMemo); selectedMemo.entityAspect.setDeleted(); dataservice.saveChanges(); } }); */ } }; });
I also tried to create a Memo object, but when I do this, EntityAspect is lost in my element! But then does modal work? How to solve all this?
UPDATE 2:
I rewrote my Memo model so that it contains an object in a variable. But PropertyPendingChanged no longer starts: S