Durandal Subrouting (Hottowel)
Asked Answered
V

2

10

Basically, I am trying to create a menu inside a menu. So, within a main menu route, there will be a vertical menu with another set of routes. When clicking on the submenu routes, only a part of the page gets updated, and the vertical menu does not reload. I am guessing it would be similar to this KO fiddle http://jsfiddle.net/dPCjM/, but there would need to another set of "ghost" KO directives in a main route view:

 <!--ko compose: {model: router.activeItem, 
            afterCompose: router.afterCompose, 
            transition: 'entrance'} -->
 <!--/ko-->

and some other configs on the durandal router...

EDIT: And to clarify, I am not trying to create a dropdown in one of the main menu items. I am trying to create a menu inside one of the views. Basically a durandal app inside a durandal app :)

IFRAMES?? :))))))))))

Vesicle answered 4/4, 2013 at 3:22 Comment(4)
Do you want the submenu to support deep linking and have it affect the browser history stack?Ghat
That would be a bonusVesicle
This is a good question, I have a need for this too.Vacillating
This can be done, I'll submit an example tonightGhat
G
15

EDIT

As of Durandal.js 2.0 the Router pluggin now has a built in Child Routers which allows for deeplinking out of the box.

/Edit

The below answer perstains to durandal 1.2

The durandal router plugin is a wrapper around sammyjs.

The router plugin allows you to control the browser history stack and also gives your spa the ability to link into pages w/in your spa.

Its pretty easy to get it to do linking 1 level deep where you have 1 main menu and pages that swap in and out. But what if you wanted to have a sub menu w/in the main menu and provide deep linking.

When the router is queued to swap views the viewmodel activator first checks if the request is for the same page in your viewmodel. If it is the same view then you can cancel the route before it happens. By canceling the route when it calls the same page this allows you to take the route parameters and handle the subroute yourself.

The method that checks to see if its calling the same page is in the viewmodel called areSameItem. You can override this method inside your main viewmodel by calling:

return App = {
  router: router,
  subPage: ko.observable('defaultSubPage'),
  activate: function () {
     router.activeItem.settings.areSameItem = function (currentItem, newItem, data) {
        if (currentItem != newItem) { return false; }
        else { App.subPage(convertSplatToModuleId(data.splat)); return true; }
     }
  }
}

Of course this is inside an amd module and router is the durandal router plugin. convertSplatToModuleId is a function that takes the splat property, which is the route values, and converts it to the module of the sub page you wish to show.

So, that part was easy but there is 1 more thing that needs to be done.

<div data-bind="compose: { model: subPage, afterCompose: router.afterCompose }"></div>

Your binding for the container of the subPages needs to call router.afterCompose because this is what tells the router that the route has been completed and its ready to handle new routes.

This is not an easy task to explain. So, I created an example and pushed it to github here.

Ghat answered 4/4, 2013 at 23:33 Comment(1)
I am almost in tears. I have emulated this with all kinds of jquery calls and created a big mess in the process. Wish I had asked much earlier..Vesicle
G
2

Just as a heads up to those interested, the upcoming Durandal js 2.0 release has baked in features for deep linking which greatly simplifies things over rolling your own deep linking based upon Evan's excellent example.

Check out the Knockout sample to see it in action, which you can grab from the latest binaries via the Durandal js github project.

Of note, it is a substantial departure from the previous version of Durandal so you'll have to do some modification to the original HotTowel template to support it as there are numerous breaking changes.

Guidepost answered 23/7, 2013 at 13:59 Comment(1)
Thanks Denis, I haven't had time to look into v2.0 but was wondering about its new router. Its good to know that it supports deeplinking out of the box. I can't wait to play w/ v2. :)Ghat

© 2022 - 2024 — McMap. All rights reserved.