I have a widget that has a drop down list, that needs to be refreshed every time I go to the view. Is there a callback that I can use in the widget's viewmodel, that is called everytime the widget is used? Something that behaves exactly like a regular viewmodel's activate callback.
The widget's activate function is not called everytime the parent view is loaded:
ctor.prototype.activate = function (settings) {
this.settings = settings;
};
But the parent viewmodel's activate function is called everytime the view is called:
var activate = function (routeData) {
var id = parseInt(routeData);
return datacontext.getEntityByID('ProductionRun', id, productionRun)
.then(loadProducts)
.fail(queryFailed);
};
I would like to move the logic about loadProducts from the parent viewmodel, to the widget's viewmodel, and in the widget's view, use the collection from the widget's viewmodel, not the parent's viewmodel. Change from:
<select data-bind="options: $parent.products, optionsText: 'name', optionsValue: 'productID', value: settings.productionRun().productID"></select>
To:
<select data-bind="options: products, optionsText: 'name', optionsValue: 'productID', value: settings.productionRun().productID"></select>
Thanks
====== Update on 2013-10-29 ======
Here's the code from App/widgets/productionRunDetails/viewmodel.js:
define([
'durandal/app',
'durandal/composition',
'messaging',
'services/datacontext',
'services/datacontext.product'
], function (app, composition, messaging, datacontext, datacontext_product) {
function myObject() {
var productionRunStatuses = ko.observableArray(datacontext.lookups.productionRunStatuses);
var isSaving = ko.observable(false);
var hasChanges = ko.computed(function () {
return datacontext.hasChanges();
});
var canSave = ko.computed(function () {
return hasChanges() && !isSaving();
});
var saveProductionRunDetailsCommand = function () {
isSaving(true);
return datacontext.saveChanges().fin(complete);
function complete() {
isSaving(false);
app.trigger(messaging.messages.productionRunDetailsWidget_saved, this);
}
}
var cancelProductionRunDetailsCommand = function () {
datacontext.cancelChanges();
}
var closeProductionRunDetailsCommand = function () {
datacontext.cancelChanges();
}
var self = this;
self.canSave = canSave;
self.productionRunStatuses = productionRunStatuses;
self.saveProductionRunDetailsCommand = saveProductionRunDetailsCommand;
self.cancelProductionRunDetailsCommand = cancelProductionRunDetailsCommand;
self.closeProductionRunDetailsCommand = closeProductionRunDetailsCommand;
}
myObject.prototype.activate = function (settings) {
this.settings = settings; //This gets called once, during the whole life cycle of the widget
};
//myObject.prototype = (function () {
// var activate = function () {
// };
// return {
// activate: activate
// }
//})(); // As soon as I add this code (myObject.prototype), the widget does not work.
var myObj = new myObject();
return myObj;
});
The widget is implement this way in the parent view:
<div data-bind="widget: {kind:'productionRunDetails', productionRun:productionRun}"></div>
I'm passing a ko observable called productionRun from the parent view to the widget (which I have available in the settings parameter within the viewmodel). There's a dropdown list in the widget that gets loaded in the parent viewmodel. I'd like to move the load operation from the parent viewmodel, to the widget's viewmodel, and change the binding from:
<select data-bind="options: $parent.products, etc
To:
<select data-bind="options: products
But in order to do that, I need to have an activate callback that gets executed everytime the parent viewmodel is activated (through navigating to that parent view).
Is this possible? I followed Durandal's example about creating widgets, but the activate callback is only called once ( http://durandaljs.com/documentation/Creating-A-Widget/ ). I'm new to Hot Towel + Durandal + Breeze. Thank you.
activate
is not getting called? Because in a newly created Durandal 2.0 project it seems it is working fine... how do you load your parent view? – nemesv