Durandal: Can not pass activationData in compose with child router

2.6k Views Asked by At

Durandal 2.0.1. I have main router and child router for one of the main routes, the code of the shell module for that route (coffee):

define ['plugins/router'], (router) ->
    router = router.createChildRouter().makeRelative({ fromParent: true })
    return {
        activationData: null
        router: router
        activate: () ->
            @activationData = <some data>
            routes = <child routes>            
            router.reset().map(routes).buildNavigationModel()
            return
    }

Html for the shell module of that route:

<div class="tab-sub-links">
    <!-- ko foreach: router.navigationModel -->
        <a tabindex="-1" data-bind="css: { active: isActive }, attr: { href: hash }, text: title"></a>
    <!-- /ko -->
    <div class="clearfix"></div>
</div>
<div class="tab-content">
    <div class="content-wrapper" data-bind="router: { transition: 'entrance', cacheViews: true, activate: true, activationData: activationData }"></div>
</div>

one of child modules:

define ['knockout'], (ko) ->
    return {
        mainData: null
        activate: (activationData)->
            @mainData = activationData //always undefined
            return
    }

The problem is: activation data is not passed to child view. I digged in compose.js and found out that activationData is passed when model is passed to compose, in my view-binding model is router.activeItem, but activeItem is empty until route is activated and compose is running before that. Why? What should I do?

EDIT:

changed binding from:

router: {cacheViews: false, activationData: activationData}

to:

compose: {model: router: activeItem, attached: router: attached, compositionComplete: router.compositionComplete, cacheViews: false, activationData: activationData}

to no avail, and that was expectable, because router binding passes params to compose binding, so thees two records actually do the same.

1

There are 1 best solutions below

6
On BEST ANSWER

Durandal's router has support for hash based parameter, but not for activationData http://durandaljs.com/documentation/Using-The-Router/. Assuming a route like customer/:customerId/orders/:orderId would allow retrieving activationData during activate e.g.

function activate(customerId, orderId){
    //retrieve activationData from backend based on customerId and/or orderId
}

Updated based on comments

http://durandaljs.com/documentation/Conversion-Guide/

The new router now not only supports parameterized routes, but also optional parameters, splats and query strings.

There's no activationData support when using the router as all information needs to be passed in as URL hash values. The recommended way to deal with that situation is to retrieve the data during activate based on the params passed in (see above).

As an alternative composition without the router could be considered. If the composed model needs to support the full life-cycle events (normally provided by the router) you'd have to use your own activator.

https://github.com/dFiddle/dFiddle-2.0/blob/gh-pages/app/masterDetail/wizard2/wizard.js#L10

define(['durandal/activator', './step', 'knockout'], function( activator, Step, ko ) {
    var ctor = function( options ) {
        ...
        this.activeStep = activator.create();
        ...
    };

    return ctor;
});

Live version: http://dfiddle.github.io/dFiddle-2.0/#master-detail/wizard2