문제

I've got a view & view model that needs to have data conditionally populated. I've noticed that the viewAttached override only gets called once per view... thus initially the logical place for all my init calls, as the data is pretty much static.

But in the instances where I pass data to the screen from another view, the activate call gets triggered before the viewAttached... so if a user hasn't navigated to the view before... their selection wont be selected as the init function wont have been called yet.

My question is as follows:

Which hook would be considered the most relevant one to use to perform any knockout bindings, or how can i modify the order of execution, and if i do... will things explode? :P (as tinkering with working parts frameworks, might end up in unstable code)

Viewmodel

var vm = {
        lookups: lookups,
        userInfo: userInfo,
        buttons: buttons,

        viewAttached: function (view) {
            $('.date').datepicker().on('show', function (ev) {
                var today = new Date();
                var t = today.getFullYear() + "-" + today.getMonth() + '-' + today.getDate();
                $(this).data({ date: t }).datepicker('update');
            });

            console.log('viewAttached');
            console.log(view);


            // should this move to the activate function?
            lookupInit();
        },

        activate: function (data) {

            console.log('activate');
            console.log(data);

            var id = data.id || undefined;

            if (id !== undefined) {
                router.isNavigating(true);
                http.json('/api/user/' + id)
                    .done(function (response) {
                        ko.viewmodel.updateFromModel(vm.userInfo, response);
                        router.isNavigating(false);
                    });
            }
        }
  };
도움이 되었습니까?

해결책

All data retrieval operation should be handled in activate. You might have to chain multiple calls if they are depended or use $.when to make multiple calls in parallel. In Durandal 1.2. make sure to return either true, false or a promise from activate to let Durandal know when it's allowed to continue composing.

Best practice for viewAttached would be to use the passed in view to limit the jQuery selector otherwise you might accidentally effect elements outside the view. e.g.

viewAttached: function (view) {
$('.date').datepicker().on('show', function (ev) ...

would become

viewAttached: function (view) {
$('.date', view).datepicker().on('show', function (ev) ...

or

viewAttached: function (view) {
$(view).find('.date').datepicker().on('show', function (ev) ...

다른 팁

ViewAttached is called each time the view is attached to the DOM, so it will be called each and every time that you have navigate to the view. ViewAttached is always called after Activate.

To do init operations, you can do that by declaring a global boolean variable in activate function.

Eg:

function activate()
{
   if(notInit){ /* do stuff */ 
       notInit = true;
   }
   /* do stuff */
}

Please look at the following links to understand Durandal's view life cycle:

http://durandaljs.com/documentation/Hooking-Lifecycle-Callbacks/

http://durandaljs.com/documentation/View-Model/

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top