5

I'm using the Hot Towel SPA project I'm trying to call a simple js function when a view is activated. What I'm seeing is that the item does not seem to be loaded when the activate function is called.

I've also tried putting the code in an initialize function called by activate as suggested on other SO posts. This does not seem to help.

So what is the recommended method in Durandal/HotTowel for calling a function on view load?

home.js (view model)

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

    return vm;

    function activate() {       
        logger.log('Home View Activated', null, 'home', true);
        return init();
    }

    function init() {
        $("#backBtn").hide();
        console.log($("#myBtn").html()); // returns undefined 
    }
});

home.html (view)

<section>  
  <div id="myBtn">test</div>
</section>
Ben Ripley
  • 2,115
  • 21
  • 33

3 Answers3

12

According to the latest Durandal docs at Interacting with the DOM, viewAttached renamed to attached, so you code using Durandal 2 will be the following:

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

return vm;

function activate() {       
    logger.log('Home View Activated', null, 'home', true);
}

function attached(view, parent) {
    $(view).find("#backBtn").hide();
    console.log($(view).find("#myBtn").html()); 
}
});
Spontifixus
  • 6,570
  • 9
  • 45
  • 63
Yevgen Safronov
  • 3,977
  • 1
  • 27
  • 38
9

When durandal attaches a view model it looks over that model for the viewAttached method. I modified your code below. It should find the jQuery elements you are looking for.

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

    return vm;

    function activate() {       
        logger.log('Home View Activated', null, 'home', true);
    }

    function viewAttached(view) {
        $(view).find("#backBtn").hide();
        console.log($(view).find("#myBtn").html()); 
    }
});

Take a look at the Composition page at the bottom for a little more about viewAttached. http://durandaljs.com/documentation/Using-Composition.html

Vinney Kelly
  • 4,975
  • 1
  • 25
  • 31
adamlj
  • 225
  • 1
  • 9
  • 1
    Also check out the [Interacting with the DOM](http://durandaljs.com/documentation/Interacting-with-the-DOM/) docs page. – blachniet May 08 '13 at 16:11
  • 1
    This answer is not correct any more, due to changes in Durandal. The viewAttached function doesn't get called any more. Also the link to the docs is broken. Please update your answer. – Teodor Sandu Oct 08 '13 at 10:11
  • 1
    As described in the documentation for [Converting to Durandal 2.0](http://durandaljs.com/documentation/Conversion-Guide.html), the `viewAttached` callback hook has been replaced with `attached`. – Vinney Kelly May 30 '14 at 18:14
2

According to the Durandal docs at Interacting with the DOM, view models have 4 callbacks they can implement in order to interact with DOM elments, each of which is passed a DOMElement representing the view:

  • getView
  • beforeBind
  • afterBind
  • viewAttached

It states that viewAttached is the most commonly used hook. See the docs for more detailed descriptions of each of the callbacks. You can see the full lifecycle in a table at the bottom of Hooking Lifecycle Callbacks.

define(['services/logger'], function (logger) {
    var vm = {
        activate: activate,
        getView: getView,
        beforeBind: beforeBind,
        afterBind: afterBind,
        viewAttached: viewAttached,
        title: 'Home'
    };

    return vm;

    function activate() {       
        logger.log('Home View Activated', null, 'home', true);
        return init();
    }

    function getView(view) {
    }

    function beforeBind(view) {
    }

    function afterBind(view) {
    }

    function viewAttached(view) {
        $("#backBtn").hide();
        console.log($("#myBtn").html()); // returns undefined 
    }
});
blachniet
  • 4,323
  • 5
  • 33
  • 34