Inherit jQuery widgets and call some base widget&#

2019-09-06 04:45发布

问题:

I have two jQuery widgets, Widget A is the base one and the Widget B inherits Widget A.

Widget A:

$(function () {
    $.widget("custom.widgetA", {

        _create: function () {
            this.element
                .addClass('ui-widget-a')
                .append(
                    $(document.createElement('div')).text('Widget A')
                );
        },

        someMethod: function() {
            return 'widget A';
        }
    });

}(jQuery));

Widget B:

$(function () {
    $.widget("custom.widgetB", $.custom.widgetA, {

        _create: function () {
            this.element
                .addClass('ui-widget-b')
                .append(
                    $(document.createElement('div')).text('Widget B')
                );

            this._super();
        },

        someOtherMethod: function() {
            return 'widget B';
        }
    });

}(jQuery));

than I apply Widget B to some HTML element

$('#widgetB').widgetB();

and now I want to call method someMethod from widget A... in order to do this I use this code

$('#widgetB').widgetA('someMethod')

but get the error message

cannot call methods on widgetA prior to initialization; attempted to call method 'someMethod'

I know if I call it this way it will work

$('#widgetB').widgetB('someMethod')

but I need to call it using the base widget... is possible to do?

here is the fiddle with my example

UPDATE

the reason why it happens this way here

回答1:

There's really nothing stopping you from initing both widgets on the same element:

$.widget("custom.widgetB", $.custom.widgetA, {

    _create: function () {
        this._super();
        $(this.element).widgetA(this.options);
    }
});

Now you can call both:

$('#widgetB').widgetA('someMethod');
$('#widgetB').widgetB('someMethod');

In your case the create function actually creates new elements (which has a jQuery shorthand $("<div>")), so you'd have to only include one of the above initializers for widgetA ie. only one of this._super() or $(this.element).widgetA()

Fiddle update


This can lead to some additional complexity if you're storing non-primitive objects on the widgetA instance, but with this model you probably shouldn't be doing that in the first place