I've tried several different approaches, but I've been unsuccessful in having my view update its contents. My view contains a list of customers
and a list of employees
.
This represents what I've tried so far omitting employees
as its essentially duplicated code.
function dbControl() {
var self=this;
self.customers = function() { $.ajax(...) }; // returns customers object
self.addCustomer = function() { $.ajax(...) };
self.delCustomer = function() { $.ajax(...) };
}
var DB = new dbControl();
var VM = {};
// Populate the VM
VM.selCustomer = ko.observable();
VM.customers = ko.mapping.fromJS(DB.customers);
VM.addCustomer = function() {
DB.addCustomer() // successfully adds to Database
VM.customers.push(); // push VM.selCustomer() into VM.customers
}
VM.delCustomer = function() {
DB.delCustomer() // succcessfully removes from Database
VM.customers.remove(); // removes VM.selCustomer() from VM.customers
}
// Knockout Binding
ko.applyBindings(VM);
The data-bind="foreach: customers"
binding works on the webpage just fine and lists all the entries.
All the AJAX calls successfully LIST/ADD/DELETE from the Database properly, but the View does not update after a successful DELETE.
I've tried adding ko.mapping.fromJS(DB.customers, VM)
to the end of the delete function in the VM as instructed in the DOCS:Then, every time you receive new data from the server, you can update all the properties on viewModel in one step by calling the ko.mapping.fromJS function again, but no luck.
I've tried adding VM.customers.valueHasMutated()
to the VM and it still doesn't update.
I've tried creating an interval to run both previous attempts:
setInterval(function() {
VM.customers = [];
VM.customers = ko.mapping.fromJS(DB.customers);
VM.customers.valueHasMutated();
}, 1000);
Am I structuring this whole project wrong?
Ok, so after more copy/pasting, I think I've solved my own problem:
The reason the View wasn't updating was because the data coming from the database was never being "re-called".
To fix the problem, within the add/delete functions in the VM, I had to call first the function that pulls the data from the server DB.getCustomers(), then make the ko.mapping.fromJS(DB.customers, {}, VM.customers) call.
function dbControl() {
var self = this;
getCustomers = function() {
$.ajax({
/* URL/TYPE/DATA/CACHE/ASYNC */
success: function() {
self.customers = data; // Now, DB.customers == Updated Data!
}
});
}
}
var DB = new dbControl();
VM = {};
VM.addCustomer = function() {
DB.addCustomer() // successfully adds to Database
//VM.customers.push(); <------ Remove the redundancy
DB.getCustomers(); // get the new list from the server
ko.mapping.fromJS(DB.customers, {}, VM.customers);
}
VM.delCustomer = function() {
DB.delCustomer() // succcessfully removes from Database
//VM.customers.remove(); <------ Remove the redundancy
DB.getCustomers(); // get the new list from the server
ko.mapping.fromJS(DB.customers, {}, VM.customers);
}