简体   繁体   中英

How to access to $(this) when bind(this) is used?

Suppose I have a form attached to the following javascript function:

$('#foo').submit(function (event)
{
    event.preventDefault();

    if (!this.validate()) {
        return;
    }

    console.log($(this).attr('action'));
}.bind(this));

now the main problem is that the submit function attached to #foo is available inside a class which contains other functions, eg: validate :

Helper.prototype.validate = function()
{
    // some content
}

I need to access to those functions using this , so I attached at the end of the submit the code: bind(this) and I'm able to invoke the validate function of Helper class simply using this.validate .

The scenario above will cause some issue on the $(this) parameter, infact if I try to access to the action of the form, then I'll get an empty string because javascript will search the variable action inside the class Helper .

If I remove bind(this) I can access to the action of the form, but I'll lose the access to validate function.

Someone have an idea to fix this?

The generic structure of the js file is this:

function()
{
    Helper.prototype.bindEventHandlers = function()
    {
        $('#foo').submit(function (event)
        {
            event.preventDefault();

            if (!this.validate()) {
                return;
            }

            console.log($(this).attr('action'));
        }.bind(this));

        Helper.prototype.validate = function()
        {
           ...
        });
    }
}

You can't.

The entire point of bind is that you replace the value of this .

If you want to have access to this and another value, then don't use bind. Store the value in a different variable. Consider an IIFE instead:

$('#foo').submit(
  function (context) {
    return function(event) {
      event.preventDefault();

      if (!context.validate()) {
        return;
      }

      console.log($(this).attr('action'));
    }
  }(this)
);

You might want to split it up to make it less unwieldy:

function thingy_factory(context) {
  function thingy(event) {
    event.preventDefault();
    if (!context.validate()) {
      return;
    }

    console.log($(this).attr('action'));
  }
  return thingy;
}

and

$('#foo').submit(thingy_factory(this));

I would say instead of relying on the keyword this , just set up a reference to the current value of this outside of the jQuery callback.

function(){
   Helper.prototype.bindEventHandlers = function(){
       var context = this;
       $('#foo').submit(function (event){
            event.preventDefault();

            if(!context.validate()){
                return;
            }

            console.log($(this).attr('action'));
        });

    }

     Helper.prototype.validate = function(){
         ...
     });
}

I moved Helper.prototype.validate out of the the bindEventHandlers , I'm assuming that's what your intention is. Might have just been a formatting error.

Before of $('#foo').submit you can add var that = this; and validate function will be called in this way: that.validate()

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