在 Select2 版本 4.x 中向数据适配器添加装饰器

Add decorator to data adapter in Select2 version 4.x

我想为我的自定义 Select2 Data Adapter 支持 MaximumInputLength 装饰器。在我的自定义数据适配器中,Utils.Decorate() 调用不执行任何操作。

看看 this gist,我可以在我初始化 select2() 的同一个地方调用 Decorator 函数,但这看起来很恶心而不是 DRY,因为我想初始化其中的许多 Select个元素。

为了对 MyDataAdapter 的所有实例启用最小输入,是否可以从适配器本身装饰该适配器?有更好的方法吗?

我的 select2() 电话:

$('select').select2({
    dataAdapter: MyDataAdapter,
    minimumInputLength: 2
});

MyDataAdapter(无依赖项):

define([...], function(Utils, MinimumInputLength, ArrayAdapter){

    function MyDataAdapter($element, options) {
        this.$element = $element;
        this.options = options;
        MyDataAdapter.__super__.constructor.call(this, $element, options);
    }

    Utils.Extend(MyDataAdapter, ArrayAdapter);
    Utils.Decorate(MyDataAdapter, MinimumInputLength); <-- does nothing

    MyDataAdapter.prototype.query = function(params, callback) {
        console.log('query!');
    };

    return MyDataAdapter;

});

您会在 the gist 中注意到他们装饰适配器的调用看起来像

var dropdownAdapter = Utils.Decorate(
  Utils.Decorate(
    DropdownAdapter,
    DropdownSearch
  ),
  AttachContainer
);

他们后来在初始化 Select2 时继续使用 dropdownAdapter。这是因为 Utils.Decorate returns 装饰 class 而不是就地装饰。您还会注意到它装饰器和适配器已经创建之后执行此操作。

因此,不要在适配器中间调用 Utils.Decorate,而应在最后调用它。在您返回完成的适配器时,或者在您返回之前。

define([...], function(Utils, MinimumInputLength, ArrayAdapter){    
    function MyDataAdapter($element, options) {
        this.$element = $element;
        this.options = options;
        MyDataAdapter.__super__.constructor.call(this, $element, options);
    }

    // Always extend after making the constructor
    Utils.Extend(MyDataAdapter, ArrayAdapter);

    MyDataAdapter.prototype.query = function(params, callback) {
        console.log('query!');
    };

    // Decorate after the adapter is built
    return Utils.Decorate(MyDataAdapter, MinimumInputLength);
});

之前你的主要问题是你没有使用从 Utils.Decorate 返回的 class。但是您可能会遇到的另一个问题是它无法正常工作,这是因为您在 query 方法被装饰后重写了它。