简体   繁体   中英

Access 'this' within Click function

Is it possible to access $(this) and perform actions such as hide() or toggle() this div in Knockout? I'm trying to access it via jQuery. Any alternative methods within the function is appreciated.

At the moment if I do this:

click: function(){ console.log(this) }

I get the $data of my viewmodel.

I know other ways of handling this action via the model of knockout but I was wondering if this is possible?

  <div data-bind="click: function(){ $(this).hide() }" class="alert alert-secondary alert-dismissible fade show" role="alert" >
         some text here
    </div>

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>

It's almost always better to handle logic on the view-model instead of cluttering your markup, however, you can access the element with "$element" instead of "this". For a better example of how things should be done refer to Tomalak's excellent answer.

data-bind="click: function(){ $($element).hide() }"

Maybe you can pass the event and access event.target and do event.target.hide() on that. Usually this kind of situation is handled by assigning this to some other variable

function sample(){
    var _this = this;
    function(){
        console.log(_this,this); // both are accessible here
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM