I have two modalviews
- MyModalViewA
(parent) and MyModalViewB
(child).
MyModalViewA
spawns MyModalViewB
, as custom binding, as well has observable array which I need to update. And it looks like:
(function () {
'use strict';
var
window = __webpack_require__(/*! window */ 10),
_ = __webpack_require__(/*! _ */ 2),
$ = __webpack_require__(/*! $ */ 12),
ko = __webpack_require__(/*! ko */ 3),
key = __webpack_require__(/*! key */ 16),
Enums = __webpack_require__(/*! Common/Enums */ 4),
Utils = __webpack_require__(/*! Common/Utils */ 1),
Links = __webpack_require__(/*! Common/Links */ 13),
Remote = __webpack_require__(/*! Remote/User/Ajax */ 14),
kn = __webpack_require__(/*! Knoin/Knoin */ 5),
AbstractView = __webpack_require__(/*! Knoin/AbstractView */ 11),
AttachmentModel = __webpack_require__(/*! Model/Attachment */ 86)
;
function MyModalViewA()
{
...some observables...
//data response which must be updated
this.rows= ko.observableArray([]);
this.getResults = Utils.createCommand(this, function()
{
kn.showScreenPopup(__webpack_require__(/*! View/Popup/SearchUsers */ 171),[oData]);
}
}
kn.constructorEnd(this);
}
module.exports = MyModelViewA;
}());
Then MyModelViewB
:
(function () {
'use strict';
var
window = __webpack_require__(/*! window */ 10),
_ = __webpack_require__(/*! _ */ 2),
$ = __webpack_require__(/*! $ */ 12),
ko = __webpack_require__(/*! ko */ 3),
key = __webpack_require__(/*! key */ 16),
Enums = __webpack_require__(/*! Common/Enums */ 4),
Utils = __webpack_require__(/*! Common/Utils */ 1),
Links = __webpack_require__(/*! Common/Links */ 13),
Remote = __webpack_require__(/*! Remote/User/Ajax */ 14),
kn = __webpack_require__(/*! Knoin/Knoin */ 5),
AbstractView = __webpack_require__(/*! Knoin/AbstractView */ 11),
AttachmentModel = __webpack_require__(/*! Model/Attachment */ 86)
;
function MyModalViewB()
{
...some observables...
this.doSearch = Utils.createCommand(this, function()
{
MyModelViewB.findUsers(userId);
}
kn.constructorEnd(this);
}
MyModelViewB.findUsers = function (userId)
{
//here I'm retriewing rows
//and I need I need to update rows from MyModalViewA
}
module.exports = MyModelViewB;
}());
Then based on an answer from Whats the best way of linking/synchronising view models in Knockout? I have tried to use PubSub
to update this.rows= ko.observableArray([]);
from MyModelViewA
.
For that I have added var postbox = ko.observable();
to MyModelViewA
constructor variables. Then in MyModelViewA
I have added
postbox.subscribe(function(newValue) {
this.rows.push(newValue);
}, this);
and after that in MyModelViewB
I have added
this.results = ko.observableArray([]);
this.results.subscribe(function(newValue) {
postbox.notifySubscribers(newValue);
});
But both views doesn't get what newValue
is neither MyModelViewB
is not updating MyModelViewA
this.rows
observable when I will hardcode newValue
in MyModelViewB
.
At that point I'm not sure if I have got correctly answer from mentioned link above to have get it to work.
Edits
I have added to top of my modules bundle code
var postbox = new ko.subscribable();
as below code
(function($) { $(function() {
window.postbox = new ko.subscribable();
});
});
was throwing error when trying to declare subscribable
Cannot read property 'subscribe' of undefined
then in the module for MyModalViewA
added simplified version from PFX answer:
postbox.subscribe(function(newValue) {
self.myTest(newValue);
console.log('New value: ' + newValue);
}, null, "NewRowAvailable"
);
and in the module for MyModalViewB
under MyModelViewB.findUsers
added
var newRow = "testing123";
postbox.notifySubscribers(newRow, "NewRowAvailable");
When I will debug that code it shows that postbox
was defined as Object {NewValueAvailable: }
but notifySubscribers
wasn't updating subscribable.
Thoughts?
Make sure that the postbox
instance is one and the same instance being shared between both viewmodels and that the notifySubscribers
and subcribe
methods follow the signatures below.
notifySubscribers(eventData, eventName);
subscribe(function(eventData) { ... }, null, eventName);
Below you find a simplified version of what you are trying to achieve.
Here only 1 search result is being passed, but it might also be more via eg. an array.
var postbox = ko.observable();
function MyModalViewA()
{
var _self = this;
_self.rows = ko.observableArray([
{ label: "foo" },
{ label: "bar" }
]);
postbox.subscribe(function(newValue) {
_self.rows.push(newValue);
}, null, "PFX.NewRowAvailable"
);
};
function MyModalViewB()
{
var _self = this;
_self.search = function() {
var newRow = { "label" : "baz" };
postbox.notifySubscribers(newRow, "PFX.NewRowAvailable");
};
};
var vma = new MyModalViewA();
ko.applyBindings(vma, $("#vma").get(0));
var vmb = new MyModalViewB();
ko.applyBindings(vmb, $("#vmb").get(0));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div id="vma">
<h3>ViewModel A</h3>
<ol data-bind="foreach: rows">
<li data-bind="text: label"></li>
</ol>
</div>
<hr />
<div id="vmb">
<h3>ViewModel B</h3>
<button data-bind="click: search">search</button>
</div>