Select2 allowclear和kickout.js [英] Select2 allowclear and knockout.js

查看:159
本文介绍了Select2 allowclear和kickout.js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过以下简单绑定使用select2和淘汰赛:

I use select2 and knockoutJs with this simple binding:

ko.bindingHandlers.select2 = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        var options = ko.toJS(valueAccessor()) || {};
        setTimeout(function () {
            $(element).select2(options);
        }, 0);
    }
};

标记:

<select class="select2" style="width:100%" data-bind="optionsCaption: '',options: $root.items,optionsText: 'description',optionsValue: 'id', value: $root.selectedItem,select2: { placeholder: 'Select an item...',allowClear: true }"></select>

有效!现在,我在Select2中启用了allowClear选项,以清除下拉列表,如Select an item...的占位符值.

it works! Now I enabled the allowClear option in Select2 to clear dropdown to a placeholder value like Select an item....

如果我单击x图标下拉列表,则会正确设置占位符,但删除后不会更新可观察的绑定值!

If I click the x icon dropdown properly sets the placeholder but knockout don't update observable binded value!

我认为我必须更改自定义绑定,添加以下内容:

I think I've to change custombinding adding something like this:

setTimeout(function () {
    $(element).select2(options).on("select2-removed", function (e) {
       ko.bindingHandlers.value.update(element, function () { return ''; });
    });
...

但是它不起作用!

推荐答案

有几个问题.

1)绑定处理程序中的update是根据值更改更新DOM ,您永远不要定义具有修改模型能力的update回调.

1) the update in bindinghandler is to update DOM based on value change, you should never define an update callback with the ability to mutate your model.

正确的方法是,在定义新的绑定处理程序时,使用init回调将所有change事件与模型挂钩,update回调仅仅是 DOM绘制例程.

The right way is, when define a new bindinghandler, use init callback to hook up all change events with the model, the update callback is merely a DOM drawing routine.

如果init提供了DOM绘图(例如select2提供的),则无需定义update回调.

If your init provided DOM drawing (such as provided by select2), you don't need to define an update callback.

因此,ko.bindingHandlers.value.update(element, function () { return ''; });行仅重绘了DOM,它没有执行您想要的操作.

Hence the line ko.bindingHandlers.value.update(element, function () { return ''; }); only redraw the DOM, it doesn't do what you want.

2)您创建的select2绑定有一些漏洞.

2) the select2 binding you created has some holes.

  • 首先,value绑定不知道select2绑定的存在,这就是您要努力的地方.
  • 第二秒,您的select2绑定必须等待其他绑定(options绑定)才能完成DOM创建,这就是为什么使用setTimeout的原因.但是ko提供了一种定义绑定顺序的方法,只需查看ko value绑定的源代码,它的定义为'after': ['options', 'foreach']
  • 第三,您的select2不响应外部更改.例如,如果您有另一个UI更新$root.selectedItem(常规选择列表),则该UI引发的更改将不会同步回您的select2.
  • first, value binding doesn't know the existence of select2 binding, that's where you struggled.
  • second, your select2 binding has to wait for other binding (the options binding) to finish DOM creation, what's why you use setTimeout. But ko provided a way to define sequence of the bindings, just look the source code of ko value binding, it's defined as 'after': ['options', 'foreach']
  • third, your select2 doesn't respond to outside change. For instance, if you have another UI to update $root.selectedItem (a normal select list), the change raised by that UI would not sync back to your select2.

解决方案

根据现有的value绑定(只是发现不需要)来定义select2绑定,并挂接所有更改事件.

Define select2 binding based on existing value binding (just found out it's not needed), and hook up all change events.

  • 我们不需要"select2-removed"事件,这全都与"change"事件有关.
  • select2提供了所有图形,我们不需要update回调.
  • 使用标志shouldIgnore中断值订户和select2更改事件处理程序之间的循环.
  • we don't need "select2-removed" event, it's all about "change" event.
  • select2 provided all drawing, we don't need update callback.
  • use a flag shouldIgnore to break the loop between value subscriber and select2 change event handler.

http://jsfiddle.net/huocp/8N3zX/6/ http://jsfiddle.net/huocp/8N3zX/9/

http://jsfiddle.net/huocp/8N3zX/6/ http://jsfiddle.net/huocp/8N3zX/9/

ko.bindingHandlers.valueSelect2 = {
    'after': ['options'],
    'init': function(element, valueAccessor, allBindings) {
        // kind of extend value binding
        // ko.bindingHandlers.value.init(element, valueAccessor, allBindings);

        var options = allBindings.get('select2Options') || {};
        $(element).select2(options);

        var value = valueAccessor();
        // init val
        $(element).val(ko.unwrap(value)).trigger("change");

        var changeListener;
        if (ko.isObservable(value)) {
            var shouldIgnore = false;
            changeListener = value.subscribe(function(newVal) {
                if (! shouldIgnore) {
                  shouldIgnore = true;
                  // this is just select2 syntax
                  $(element).val(newVal).trigger("change");
                  shouldIgnore = false;
                }
            });

            // this demo only works on single select.
            $(element).on("change", function(e) {
                if (! shouldIgnore) {
                    shouldIgnore = true;
                    if (e.val == '') {
                        // select2 use empty string for unselected value
                        // it could cause problem when you really want '' as a valid option
                        value(undefined);
                    } else {
                        value(e.val);
                    }
                    shouldIgnore = false;
                }
            });
        }

        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            if (changeListener) changeListener.dispose();
            $(element).select2("destory");
        });
    }
};

这篇关于Select2 allowclear和kickout.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆