Is it possible to access $(this) and perform actions such as hide() or toggle() this div in Knockout?
Yes, but you should not do that.
Any jQuery code (beyond the $.ajax()
utility functions) and any other code that does DOM interaction (modification, traversal, event handling, style changes) should stay completely out of both your viewmodel and your view.
- Your viewmodel manages the state of your application, not its looks.
- The way to manage the looks of the application is by binding viewmodel properties to view properties.
- The view should be fully dependent on the viewmodel, but the viewmodel should have zero dependencies on the view.
- Adding code that calls jQuery
.hide()
in the viewmodel introduces a dependency to the view inside the viewmodel. Assume you change your view and .hide()
is no longer the right thing to do. Now you have to change the viewmodel as well - without adding any actual functionality.
- Adding code that calls jQuery
.hide()
in the view leaves the state inside the viewmodel in the dark about a change in how things are displayed. You lose control over how the viewmodel looks and are gradually forced to add even more hacks like this.
- Use the existing bindings (there are bindings all the basic interactions like showing or hiding elements, adding event handlers, interacting with form elements) or write new bindings for special behavior.
So in your case, what you need is
- a viewmodel property that tracks if the item should be visible
- a function to set this property
- the
visible
binding
In the case of a dialog, let's call that property isVisible
and let it default to true
.
Viewmodel:
function Alert() {
var self = this;
self.isVisible = ko.observable(true);
self.message = ko.observable("some text here");
self.dismiss = function () { self.isVisible(false); };
}
View, wrapped for legibility:
<div
data-bind="
text: message,
click: dismiss,
visible: isVisible,
text: message
"
class="alert alert-secondary alert-dismissible fade show"
role="alert"
></div>