I have multiple view models contained in one master view model. I am trying to insert an item into an array in viewmodel A from viewmodel B. In my log I see the item getting added to the array but it is not updating the UI.
—–HTML
<form data-bind="submit: RolesVM.addRole">
<select name="app" data-bind="options:ApplicationsVM.applications,optionsText:'name', value: RolesVM.application"><option></option></select></td>
<input data-bind='value: RolesVM.role, valueUpdate: "afterkeydown"'/>
<button>Add Role</button>
</form>
<ul data-bind="foreach: ApplicationsVM.applications">
<span data-bind="text:name"></span>
<ul data-bind="foreach: roles">
<li data-bind="text:name"></li>
</ul>
</ul>
—–JS
function MasterVM(applicationsVM, rolesVM) {
this.ApplicationsVM = applicationsVM;
this.RolesVM = rolesVM;
}
function ApplicationsVM() {
var self = this;
self.applications = ko.observableArray([]);
self.Populate = function () {
var allData = jQuery.parseJSON('[{ "name": "app 1", "roles": [{ "name": "role 1" }] }, { "name": "app 2", "roles": [{ "name": "role 1" }] }]');
var mappedApplications = $.map(allData, function (item) {return new Application(item);});
self.applications(mappedApplications);
};
}
function RolesVM() {
var self = this;
self.application = ko.observable();
self.role = ko.observable();
self.addRole = function () {
self.application().roles().push(self.role());
console.log(self.application().roles());
};
}
function Application(data) {
this.name = data.name;
this.roles = ko.observableArray($.map(data.roles, function(item) { return new Role(item.name); }));
}
function Role(data) {
this.name = data;
}
var applicationsVM = new ApplicationsVM();
applicationsVM.Populate();
var rolesVM = new RolesVM();
ko.applyBindings(new MasterVM(applicationsVM, rolesVM));
You will want to call
pushon the observableArray directly and not the underlying array. This is what notifies any subscribers that it has changed. So, you would wan to do:rather than: