Reputation: 2342
So I'm working with multiple view models using KnockoutJS, like this:
function firstViewModel() {
var self = this;
self.dataArray = ko.observableArray([
{ title: "title1", theData: "data1" },
{ title: "title2", theData: "data2" },
{ title: "title3", theData: "data3" },
]);
};
function secondViewModel() {
var self = this;
self.addData = function() {
firstViewModel.dataArray.push({ title: "newTitle", theData: "newData" });
// trying to trigger dataArray in firstViewModel, doesn't work
}
};
ko.applyBindings(new firstViewModel(), document.getElementById('first'));
ko.applyBindings(new secondViewModel(), document.getElementById('second'));
Then something like:
<div id="first" data-bind="with: dataArray">
<ul data-bind="foreach: $data">
<li data-bind="text: theData"></li>
</ul>
</div>
<div id="second">
<button data-bind="click: addData">add</button>
</div>
The reason it's structured like this is because I have a 3rd view model and the elements overlap in the DOM. I couldn't figure out how to get this to work either.
Is there any way to keep the structure and reference firstViewModel inside of secondViewModel? firstViewModel.theData.push("newData"); clearly doesn't work, but I thought I'd include it to further clarify what I'm looking to do.
I'm brand new to KO - sorry if it's a stupid question.
EDIT: Looks like I got it!
If I remove 'self' from the firstViewModel it works...
dataArray = ko.observableArray([
{ title: "title1", theData: "data1" },
{ title: "title2", theData: "data2" }
]);
then
self.addData = function() {
dataArray.push({ title: "newTitle", theData: "newData" });
}
I don't know yet if there are consequences of removing the 'self', but it's working so far.
Upvotes: 1
Views: 443
Reputation: 5147
Personally, I prefer to keep my models de-coupled, and use a publish/subscribe pattern to allow them to talk to each other. See my answer to Variable Dependency with knockoutJS
In addition, if you do want to go down that road, you can also look at knockout postbox to accomplish the same thing.
Upvotes: 1
Reputation: 15053
You could pass a reference of the first viewmodel:
function firstViewModel() {
var self = this;
self.dataArray = ko.observableArray([
{ title: "title1", theData: "data1" },
{ title: "title2", theData: "data2" },
{ title: "title3", theData: "data3" },
]);
};
function secondViewModel(firstViewModel) {
var self = this;
self.addData = function() {
firstViewModel.dataArray.push({ title: "newTitle", theData: "newData" }); // doesn't work
}
};
var firstVm = new firstViewModel();
var secondVm = new secondViewModel(firstVm);
ko.applyBindings(firstVm, document.getElementById('first'));
ko.applyBindings(secondVm, document.getElementById('second'));
Upvotes: 0