Reputation: 22643
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
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