Gildas.Tambo
Gildas.Tambo

Reputation: 22643

Is there a better way to access durandal current view from subscribtion callback?

To be sure that i am accessing the current view i can do this:

function attached(view, parent) {
    $("#element",view).hide();
}

This will return an undefined

viewModel.selectedcategory.subscribe(function (data,view) {
    console.log(data,view);
    $("#element",view).hide();
});

so what i am doing to access the view is, i define a global Variable currentView like this:

var currentView,

viewModel = {
   activate: activate,
   attached: attached,
   selectedcategory: ko.observable(false)
}

viewModel.selectedcategory.subscribe(function (callback) {
    console.log(callback, activeView);// now i can access the view 
    $("#element",activeView).hide();
});
return viewModel;

function attached(view, parent) {
    currentView = view; // update currentView
    $("#element",view).hide();
}

Is there a better way to do the same with subscribe like

viewModel.selectedcategory.subscribe(function (subscribeView, subscribeParent) {


});

Upvotes: 1

Views: 218

Answers (1)

user3174746
user3174746

Reputation:

No need to reference the "current view" the way you are doing it--essentially, you're caching it.

In your attached handler, do this:

var $view = $(view);

Then, proceed to use $view in that function.

If you're tending towards caching the view, then you haven't modularized your code enough. For example, a common refactoring for caching a view is to create a custom Knockout binding. In your case, you could create a simple custom Knockout binding for hide(), which you might call toggle():

ko.bindingHandlers.toggle = {        
    update: function(element, valueAccessor) {
        // Initially set the element to be instantly visible/hidden depending on the value
        var value = valueAccessor();
        $(element).css('visibility', ko.unwrap(value));           
    }
};

Using this binding is trivial (I pulled this from my code):

<div class="ts-message__datetime">
    <div class="ts-data--readonly" data-bind="toggle: showMessageDates(), text: messageBo().created(), css: cssClassSpeechBubbleDates()"></div>
</div>

So, now, instead of caching the view so you can show/hide, create an observable on the viewModel (in my case above, I have an observable called showMessageDates that defaults to hidden):

var showMessageDates = ko.observable(false);

In your viewModel, anytime you wish to affect the show/hide state of your element, just change the observable's value.

To answer your question more pointedly, yes, there is a better way than subscribing: custom Knockout bindings!

Upvotes: 1

Related Questions