Durandal Subrouting (Hottowel)

那年仲夏 提交于 2019-11-28 17:40:00

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!