【问题标题】:Select2 Knockout nulti-select setting value issueSelect2 Knockout 多选设置值问题
【发布时间】:2020-12-01 20:39:21
【问题描述】:

所以我有许多使用 Knockout 绑定的 select2 下拉菜单。 最初它似乎工作正常。当用户进行选择时(多选)。模型更新了,生活还不错。 当您从模型中获得要显示为默认选择的值时,我的问题就出现了。 例如在编辑某些东西时。您使用预先填充的值加载表单。

这是我的绑定处理程序

ko.bindingHandlers.select2 = {
    init: function (el, valueAccessor, allBindingsAccessor) {
        ko.utils.domNodeDisposal.addDisposeCallback(el,
            function () {
                $(el).select2('destroy');
            });

        var allBindings = allBindingsAccessor(),
            select2 = ko.utils.unwrapObservable(allBindings.select2);

        $(el).select2(select2);
    },
    update: function (el, valueAccessor, allBindingsAccessor) {
        var allBindings = allBindingsAccessor();

        if ("value" in allBindings) {
            if ((allBindings.select2.multiple || el.multiple) && allBindings.value().constructor !== Array) {
                $(el).val(allBindings.value().split(',')).trigger('change');
            } else {
                $(el).val(allBindings.value()).trigger('change');
            }
        } else if ("selectedOptions" in allBindings) {
            var converted = [];
            var textAccessor = function (value) { return value; };
            if ("optionsText" in allBindings) {
                textAccessor = function (value) {
                    var valueAccessor = function (item) { return item; }
                    if ("optionsValue" in allBindings) {
                        valueAccessor = function (item) { return item[allBindings.optionsValue]; }
                    }
                    var items = $.grep(allBindings.options(), function (e) { return valueAccessor(e) === value });
                    if (items.length === 0 || items.length > 1) {
                        return "UNKNOWN";
                    }
                    return items[0][allBindings.optionsText];
                }
            }
            $.each(allBindings.selectedOptions(),
                function (key, value) {
                    converted.push({ id: value, text: textAccessor(value) });
                });
            $(el).select2("data", converted);
        }
        $(el).trigger("change");
    }
};

selectedoptions 绑定到一个 Guid 列表。这是javascript端的字符串列表。 我相信 Select2 选择需要字符串才能设置选定的值。

我的选择如下所示:

<select class="form-control input-sm multi-select" data-bind="selectedOptions: BrandIds, options: Brands,  valueAllowUnset: true, optionsText:'Description', optionsValue: 'Value', select2:{ placeholder: 'Please Select...', allowClear: true, multiple:'multiple'}, css: { 'jackpot-input-error': BrandIds.error() && BrandIds.isModified() }" multiple></select>

所以我发现正在发生的是从 BrandIds 中的服务器返回的初始值被删除。我在订阅 BrandIds 时确定了这一点。订阅函数的参数如下所示

[
{
    "status": "deleted",
    "value": "cd1f6c04-b7ae-479e-b722-65f837e65ec2",
    "index": 0
},
{
    "status": "deleted",
    "value": "bd66ebe1-080b-4455-9094-bf0464d4adbf",
    "index": 1
}

]

【问题讨论】:

  • 如果你还没有写过这个绑定处理程序(你还没有写过),请链接到你使用过的源代码,以供参考和表扬。

标签: knockout.js jquery-select2


【解决方案1】:

我已经删除了绑定处理程序的整个update 部分,这似乎毫无意义。 Knockout 将处理 optionsTextoptionsValue 绑定。

Knockout 操纵隐藏在背景中的原始&lt;select&gt; 元素,select2 注意到这些操纵并相应地更新其小部件。好像真的没必要插手。

请注意以下示例中的两个选项是如何从视图模型的初始状态中预先选择的。当您通过自己的函数更改 BrandIds 可观察数组中的项目时,例如在一个 Ajax 请求之后,应该会发生同样的事情。

ko.bindingHandlers.select2 = {
    init: function (el, valueAccessor, allBindings) {
        var options = ko.unwrap(valueAccessor());

        $(el).select2(options);
        ko.utils.domNodeDisposal.addDisposeCallback(el, function () {
            $(el).select2('destroy');
        });
    }
};

var vm = {
  BrandIds: ko.observableArray(["ID_A", "ID_C"]),
  Brands: ko.observableArray([
    {Description: 'Brand A', Value: "ID_A"},
    {Description: 'Brand B', Value: "ID_B"},
    {Description: 'Brand C', Value: "ID_C"},
    {Description: 'Brand D', Value: "ID_D"}
  ])
};

ko.applyBindings(vm);
select {
    width: 300px;
}
pre {
    position: absolute;
    top: 10px;
    right: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.debug.js" integrity="sha512-per7WBYe3cT9aIDMoF74rYR7wpEDPqyncWqWzBGmJBnhp8H3ZD5fRdTM16IO5ePUEuBlH9DMKF7rHvuazhvDBA==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js" integrity="sha512-2ImtlRlf2VVmiGZsjm9bEyhjGW4dU7B6TNwh/hx/iSByxNENtj3WVE6o/9Lj4TJeVXPi4bnOIMXFIJJAeufa0A==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" integrity="sha512-nMNlpuaDPrqlEls3IX/Q56H36qvBASwb3ipuo3MxeWbsQB1881ox0cRv7UPTgBlriqoynt35KjEwgGUeUXIPnw==" crossorigin="anonymous" />

<select data-bind="
  selectedOptions: BrandIds,
  options: Brands,
  optionsText: 'Description',
  optionsValue: 'Value',
  select2: {
    placeholder: 'Please Select...',
    allowClear: true,
    multiple: 'multiple'
  }
" multiple></select>

<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

【讨论】:

  • 感谢您的评论。我将按照建议删除更新。如果不需要
  • @LudwigNel 对于您的下一个问题,请制作一个像上面那样的可运行示例,以重现您看到的问题/错误。当人们不必猜测您的代码时,他们更容易弄清楚发生了什么。
  • 我会确保将来有一个可运行的示例。对此感到抱歉
【解决方案2】:

所以结果证明与淘汰赛或select2无关。 我们有一个自定义连接,我们建立并发送到前端以绑定到我们的选择。 这里的字符串值是 guid 的大写字符串表示。 用于绑定到 selectedOptions 的 BrandIds 包含一个全小写的 guid 列表。 所以归结为价值观不同的情况。

【讨论】:

    猜你喜欢
    • 2013-11-24
    • 2019-02-22
    • 1970-01-01
    • 2021-01-24
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 2012-10-05
    相关资源
    最近更新 更多