In a single page app built using Durandal, I have a settings view, with different sections. I use a childRouter to resolve the different sections.
In this application, a lot of code hooks into the composition lifecycle events that Durandal uses. For example, this custom binding:
ko.bindingHandlers.autoFocus = {
init: function (element) {
var $element = $(element),
setFocus = function () {
$element.focus();
};
router.on('router:navigation:composition-complete', setFocus);
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
router.off('router:navigation:composition-complete', setFocus);
$element = null;
});
}
};
This custom binding has functioned perfectly so far, setting focus to the field the binding was applied to when the view is displayed.
However, with the child router, the timing is off. It seems that the main router triggers the 'router:navigation:composition-complete'
event when the 'settings' view is loaded. At this point, the child view is not yet displayed, and the element with the autofocus binding does not get the focus. This is illustrated even more clearly when navigating between settings pages: on leaving a page, the field with the autofocus binding on the old child view gets the focus, then the new child view is displayed without a focused element.
Is there any way to get the child router to omit events as well? Or possibly to get the main router to postpone the events till the child router is done?
I've also read that this applies in other stages of composition as well: e.g. the deactivate callback will not be called on the viewmodel of a child view. So a general fix for event triggering on child routers would be the ideal solution I'm looking for.
Thanks in advance.
Try this:
ko.bindingHandlers.autoFocus = {
init: function (element) {
var $element = $(element),
setFocus = function (child, parent, context) {
$element.focus();
if (child.router)
child.router.on('router:navigation:composition-complete', function () { $element.focus(); });
};
router.on('router:navigation:composition-complete', setFocus);
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
router.off('router:navigation:composition-complete', setFocus);
$element = null;
});
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With