简体   繁体   中英

jQuery Widget Factory access options in a callback method

I'm trying to create a jQuery control using the widget factory. The idea is that I turn a button into a jQuery button, give it an icon, and register the click event for that button such that when invoked, it displays a calendar control on a textbox , whose id is passed in as an option to the widget method:

$.widget("calendarButton", {
    options: {
        textFieldId: ''
    },
    _create: function () {
        this.element.button(
     {
         icons: {
             primary: "ui-icon-calendar"
         }
     }).click(function () {
         if (this.options.textFieldId != '') {
             $(this.options.textFieldId).datetimepicker('show');
             return false;
         }
     });
    }
});

The problem with this however, is that this.options is undefined when the click handler is invoked; which makes sense since the method has a different scope. So I tried to see if there is a way to define a "static" variable which then can be accessed inside the callback method. I found this answer that explained how to create variables inside a wrapper function like this:

(function ($) {

    var $options = this.options;

    $.widget("calendarButton", {
        options: {
            textFieldId: ''
        },
        _create: function () {
            this.element.button(
         {
             icons: {
                 primary: "ui-icon-calendar"
             }
         }).click(function () {
             if ($options.textFieldId != '') {
                 $($options.textFieldId).datetimepicker('show');
                 return false;
             }
         });
        }
    });
})(jQuery);

But it still reports that $options is undefined. Is there a way to achieve this? I'm trying to avoid requiring the callback function be passed in since it'll be pretty much the same for all instances. Any help is appreciated.

After playing with it for a few hours, I finally came across the jQuery Proxy method which is exactly what I was looking for. I changed the code a little bit to look like this:

$.widget("calendarButton", {
    options: {
        textFieldId: ''
    },
    _create: function () {
        this.element.button(
         {
             icons: {
                 primary: "ui-icon-calendar"
             }
         }).on("click", $.proxy(this._clickHandler, this));
    },
    _clickHandler: function () {
        if (this.options.textFieldId != '') {
            $(this.options.textFieldId).datetimepicker('show');
        }
    }
});

Notice that instead of implementing the click callback directly, I'm essentially creating a delegate that points to my private _clickHandler function, which itself runs on the same context as the $.widget() method (since the second argument of $.proxy(this._clickHandler, this) returns $.widget() 's context) hence availablity of the options variable inside the method.

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