I've got a view & view model that needs to have data conditionally populated. I've noticed that the viewAttached override only gets called once per view... thus initially the logical place for all my init calls, as the data is pretty much static.
But in the instances where I pass data to the screen from another view, the activate call gets triggered before the viewAttached... so if a user hasn't navigated to the view before... their selection wont be selected as the init function wont have been called yet.
My question is as follows:
Which hook would be considered the most relevant one to use to perform any knockout bindings, or how can i modify the order of execution, and if i do... will things explode? :P (as tinkering with working parts frameworks, might end up in unstable code)
Viewmodel
var vm = {
lookups: lookups,
userInfo: userInfo,
buttons: buttons,
viewAttached: function (view) {
$('.date').datepicker().on('show', function (ev) {
var today = new Date();
var t = today.getFullYear() + "-" + today.getMonth() + '-' + today.getDate();
$(this).data({ date: t }).datepicker('update');
});
console.log('viewAttached');
console.log(view);
// should this move to the activate function?
lookupInit();
},
activate: function (data) {
console.log('activate');
console.log(data);
var id = data.id || undefined;
if (id !== undefined) {
router.isNavigating(true);
http.json('/api/user/' + id)
.done(function (response) {
ko.viewmodel.updateFromModel(vm.userInfo, response);
router.isNavigating(false);
});
}
}
};
All data retrieval operation should be handled in activate
. You might have to chain multiple calls if they are depended or use $.when
to make multiple calls in parallel. In Durandal 1.2. make sure to return either true, false or a promise from activate to let Durandal know when it's allowed to continue composing.
Best practice for viewAttached
would be to use the passed in view
to limit the jQuery selector otherwise you might accidentally effect elements outside the view. e.g.
viewAttached: function (view) {
$('.date').datepicker().on('show', function (ev) ...
would become
viewAttached: function (view) {
$('.date', view).datepicker().on('show', function (ev) ...
or
viewAttached: function (view) {
$(view).find('.date').datepicker().on('show', function (ev) ...