javascriptdurandalbrowser-historydurandal-navigation

Durandal child views not adding to history and being ignored when using the browser's back button


In a Durandal application I'm working on there's a page with tabs at the top which take the user into child views. These tabs work perfectly and are configured like so:

var childRouter = router.createChildRouter()
    .makeRelative({ moduleId: 'viewmodels/admin/sections', fromParent: true })
    .map([
        { route: [''], moduleId: 'index', title: 'Admin', nav: false },
        { route: 'settings', moduleId: 'settings', title: 'Settings', nav: true },
        ...
    ]).buildNavigationModel();

I also have a navigation function which executes every time a tab is clicked, that looks like this:

function navigate(route) {
    router.navigate(route.hash, { replace: true, trigger: true });
}

The page's URL updates as expected. Going from the default admin child view (.../#admin) to the Settings tab will update the URL to .../#admin/settings. However the problem is that despite replace: true being specified the view change doesn't appear to be stored in the browser history.

If I open a new browser tab on the #admin page and navigate to the #admin/settings page the browser appears to think the only history entry prior to this was the opening of the new tab:

Browser Lack of History

If I then navigate away from the #admin section altogether, the last tab I was on does appear to get remembered in the browser history (in this case, the Settings tab I was on), but there's no entry for the main #admin page visited beforehand:

Browser History, but not enough

If I go from #admin to #admin/settings and then back to #admin I'll instead only see a reference to the main Admin page in the history, and no mention of the Settings page.

Does anyone know what I've missed that prevents the history from being updated every time the child view changes?


Solution

  • I've figured out that leaving .mapUnknownRoutes() blank instead of defining which pages to map completely fixes the problem.

    I was doing this:

    .mapUnknownRoutes('not-found', 'not-allowed')
    

    Now I'm doing this:

    .mapUnknownRoutes()
    

    Nothing appears to have broken (the 'not-found' and 'not-allowed' pages are still accessible), but now the back button works as intended.