0
votes

I have an issue that I haven't been able to find an answer to.

I have a project set up using the Hot Towel template. Everything is working except for one particular line. It is not binding the attributes to the anchor tag. Here is the line:

<a class="nav-button" data-bind="attr: {'data-target': router.navigationModel()[1].hash, href: router.navigationModel()[1].hash }">

This doesn't seem to be working. This is in a view called nav that I am calling through its view model in the shell.html like so:

 <div data-bind="compose: 'viewmodels\\nav'">
 </div>

I guess the part that is confusing me is that when I was calling it like below, it was working:

 <div data-bind="compose: { view: 'nav' }">
 </div>

I also confirmed that something like this will bind the attributes, when calling the viewmodel:

<a class="nav-button" data-bind="attr: {'data-target': 'blah', href: 'blah'}">

It just doesn't work when I use the router instead of 'blah'. Is there something different I have to do get this to work when I am calling the viewmodel instead of the view.

For reference, here is my route setup. Its pretty simple at the moment.

var routes = [
            { route: '', moduleId: 'home', title: 'Home', nav: 1 },
            { route: 'inbox', moduleId: 'SubNavigation/inbox', title: 'Inbox', nav: 2 }];

Thanks!

Update

After doing some research, I feel that I may be using the routers wrong. So I want to write out exactly what I am doing:

Here is my shell.js

define(['durandal/system', 'plugins/router', 'services/logger'],
function (system, router, logger) {
    var shell = {
        activate: activate,
        router: router
    };

    return shell;

    //#region Internal Methods
    function activate() {
        return boot();
    }

    function compositionComplete(view, parent) {
        $(".nav-button").on("click", function (event) {
            showSubNav(this);
            event.preventDefault();

        });
    }

    function boot() {
        //log('Hot Towel SPA Loaded!', null, true);

        router.on('router:route:not-found', function (fragment) {
            logError('No Route Found', fragment, true);
        });


        var routes = [
            { route: '', moduleId: 'home', title: 'Home', nav: 1 },
            { route: 'inbox', moduleId: 'SubNavigation/inbox', title: 'Inbox', nav: 2 }];


        return router.makeRelative({ moduleId: 'viewmodels' }) // router will look here for viewmodels by convention
            .map(routes)            // Map the routes
            .buildNavigationModel() // Finds all nav routes and readies them
            .activate();            // Activate the router



    }

    function log(msg, data, showToast) {
        logger.log(msg, data, system.getModuleId(shell), showToast);
    }

    function logError(msg, data, showToast) {
        logger.logError(msg, data, system.getModuleId(shell), showToast);
    }
    //#endregion
});

And here is my nav.js

define(['services/logger'], function (logger) {
var title = 'Nav';
var vm = {
    activate: activate,
    compositionComplete: compositionComplete
};

return vm;

//#region Internal Methods
function activate() {
    logger.log(title + ' View Activated', null, title, true);
    return true;
}

function compositionComplete() {
    $(".nav-button").on("click", function (event) {
        showSubNav(this);
        event.preventDefault();

    });
}



function showSubNav(link) {

    var target = $(link).data("target");

    $(".navigation-sub").removeClass("current");
    $(".active").removeClass();

    var isactive = $("body").find(".current");

    if (isactive.length == 0) {
        $("body").addClass("subnav-active");
    }

    $(target).addClass("current");
    $(link).addClass("active");


};
//#endregion
});

I'm thinking there is something I need to do in my nav.js to use the router from shell.js, but I'm not sure exactly what.

1
I feel like I'm missing a couple of things in your question, which comes down to what the router object is. That said, what do you see in the browsers console log when you add uniqueName: console.log(router) and/or uniqueName: console.log(router.navigationModel()) to the data-bind of your anchor element? - Major Byte
data-target is typically used for DOM manipulation or similar things when you don't follow an MVC or MVVM type pattern. What are you trying to accomplish in Durandal by using it? Why not just follow convention and do the action in the view model or something? - PW Kad
@MajorByte, I haven't tried that yet, but I did look at the console messages that are appearing. There is one that says "Message: 'router ' is undefined". That seems like a clue. Looking into that now. - chuckw87
@PWKad, data-target is being used for some jquery code. I inherited this code from someone else, so that my change in the future. Thanks - chuckw87
I added some more of my code to my original question - chuckw87

1 Answers

0
votes

I got this to work by moving my router code that I have in my shell viewmodel to the nav viewmodel. This is now accomplishing what I wanted to do. Just basically getting more familiar with the framework I suppose. I thought that I absolutely had to have my route set up in my shell view. Thanks!