简体   繁体   中英

Calling prototype method from another method

I am trying to call a prototype method from a jquery event handler. I have the code like this:

$('#' + this.ID + ' .selMake').on('change', this.getCarModel());

I get an error saying: Uncaught TypeError: Object [object global] has no method 'getCarModel'

What am I doing wrong here?

The first thing you need to do is remove the parentheses from the function. What your code is currently expecting is for getCarModel to return a function which is then being called when the event is triggered.

It looks like this is what you would like to do:

 $('#' + this.ID + ' .selMake').on('change', that.getCarModel);

Not this:

 $('#' + this.ID + ' .selMake').on('change', that.getCarModel());

If you want to call the function that way, you can do as follows:

 var that = this;
 $('#' + this.ID + ' .selMake').on('change', function () {
     that.getCarModel();
 });

Above, you are passing an anonymous function as an argument which will execute the code inside of it.

In the functions above, the definition of this will depend on the element that triggered the event. If you want the definition of this to be tied to your this object, you can do the following:

The most simple, understandable way is to use the that variable:

var that; 
$('#' + this.ID + ' .selMake').on('change', that.getCarModel); // This will execute the function this.getcarModel

You can also use the bind method in browsers that support ES5.

$('#' + this.ID + ' .selMake').on('change', this.getCarModel.bind(this));

The second argument to .on() should be a function. You're calling the function when you bind the handler, not when the event occurs. It should be:

var self = this;
$('#' + this.ID + " .selMake').on('change', function() {
    self.getCarModel();
});

You need to use the local variable self so this will be saved in the closure. See

"this" keyword in event methods when using JavaScript prototype object

for details about this.

Use this code:

vehicleSelect.prototype.getCarMakes = function() {
  // Optional parameters
  var options = {};

  var select = $('#' + this.ID + ' .selMake'),
      that = this;

  select.on('change', function(e) {
    that.getCarModel();
  });

  // Callback function to be called when the API response is returned
  function success(res) {
    for (var i=0; i<res.makes.length; i++) {
      $("<option>",{
        value: res.makes[i].niceName,
        html: res.makes[i].name
      }).appendTo(select);
    }
    select.removeAttr("disabled");
    select + $(' option[value="placeholder"]').html('Select Make');
  }
  // Oops, we have a problem!
  function fail(data) { console.log(data); }
  // Fire the API call
  this.res.api('/api/vehicle/v2/makes', options, success, fail);
};

For why you can't just use select.on('change', this.getCarModel) see this question (which also provides alternative solutions).

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