Knockout.js 与多个 Select2 绑定

Posted

技术标签:

【中文标题】Knockout.js 与多个 Select2 绑定【英文标题】:Knockout.js binding with multiple Select2 【发布时间】:2014-02-03 13:07:14 【问题描述】:

我的问题是,我何时将 Select2 与 Multiple 与 Knockout View Model 绑定。选择其中一个选项后,数据第二次丢失

敲除代码

$(window).load(function () 

ko.bindingHandlers.select2 = 
    init: function (element, valueAccessor, allBindingsAccessor) 
        var obj = valueAccessor(),
            allBindings = allBindingsAccessor(),
            lookupKey = allBindings.lookupKey;
        $(element).select2(obj);
        if (lookupKey) 
            var value = ko.utils.unwrapObservable(allBindings.value);
            $(element).select2('data', ko.utils.arrayFirst(obj.data.results, function (item) 
                return item[lookupKey] === value;
            ));
        

        ko.utils.domNodeDisposal.addDisposeCallback(element, function () 
            $(element).select2('destroy');
        );
    ,
    update: function (element) 
        $(element).trigger('change');
    
;

ko.applyBindings(new ViewModel());
function ViewModel() 
    var self = this;

    self.MetricsModel = ko.observableArray([]);

    GetMetrics();

    function GetMetrics() 
        $.ajax(
            url: '/Admin/GetMetrics',
            type: "POST",
            dataType: "json",
            success: function (returndata) 
                self.MetricsModel(returndata);
            ,
            error: function () 
                alert("eRROR GET Applications");
            
        );
    ;


$("#application-select-metrics").select2();    
    

html 文件

    <select multiple="multiple" id="application-select-metrics" class="form-control" data-bind="options: MetricsModel, optionsText: 'Metrics_Name', OptionsValue:'Metrics_ID', optionsCaption: 'Choose...', select2: "></select>
@*<select multiple="multiple" id="application-select-metrics" class="form-control">
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
    <option>5</option>
</select>*@

请注意,注释部分,即硬编码值有效,它允许我选择多个值,并且使用 Knockout 它第一次有效,我得到一个填充列表,但在选择一次后,第二次数据丢失。

请帮忙,

谢谢,

编辑: 正如 Hanes 所提到的,我已经编辑了代码,并引入了自定义绑定,但它仍然不起作用,我认为自定义绑定的更新部分工作不正常,因为下拉填充一次但无法绑定第二次。任何帮助将不胜感激。

【问题讨论】:

嗨,伙计,我的代码是正确的。我从 ajax 调用中得到一个对象数组。这将反过来填充我的 MetricsModel。我第一次选择任何值时可以进行多项选择,但是当我选择其他值时,我第二次选择时得到“未找到匹配项”。使用选项硬编码选择,它就像一个魅力。 代码确实是正确的。小提琴是错误的,因为模拟数据以错误的格式返回。更新小提琴:jsfiddle.net/2Q37X/1 抱歉,我对返回数据的假设是错误的!我已经删除了我之前的评论。 【参考方案1】:

@rniemeyer 不久前在 JSFiddle 上提出了这个问题,应该可以帮助您:

http://jsfiddle.net/rniemeyer/R8UF5/

他的小提琴,更新

在更新值时使用以下绑定和几个小提琴:

ko.bindingHandlers.select2 = 
  init: function(element, valueAccessor, allBindingsAccessor) 
    var obj = valueAccessor(),
      allBindings = allBindingsAccessor(),
      lookupKey = allBindings.lookupKey;

    setTimeout(function()  
      $(element).select2(obj);
    , 0);
    
    if (lookupKey) 
      var value = ko.utils.unwrapObservable(allBindings.value);
      $(element).select2('data', ko.utils.arrayFirst(obj.data.results, function(item) 
        return item[lookupKey] === value;
      ));
    

    ko.utils.domNodeDisposal.addDisposeCallback(element, function() 
      $(element).select2('destroy');
    );
  ,
  update: function(element) 
    $(element).trigger('change');
  
;

【讨论】:

lookupKey 是做什么的?它总是以undefined 出现。我在 select2 文档中找不到任何关于它的信息。 这是一个经过调整的版本(带有更新的外部参考 URL),它适用于级联下拉菜单。 jsfiddle.net/DonovanWoodside/jmtwadu5【参考方案2】:

首先,回应 cmets:您的代码是正确的。 Jeroen 所做的 JSFiddle 在模拟的 ajax 调用中引入了错误:他返回了一个整数数组,而不是具有正确属性的对象。只有在应用 select2 时才会出现此问题。

原因

您正在应用 select2,但 select2 不能很好地与 Knockout 配合使用。为什么要这样做?它对 Knockout 和您的视图模型一无所知,也不知道如何与它相处融洽。

解决方案

您需要一个用于 select2 控件的剔除自定义绑定。淘汰赛自定义绑定是在您的淘汰赛代码和第 3 方插件之间创建集成的方式。为您编写和解释这样的自定义绑定对于这个答案来说有点太多了,所以我会给您以下链接: https://github.com/ivaynberg/select2/wiki/Knockout.js-Integration

有一个解决方案可以帮助您解决问题。它们还链接到 JSFiddle,总而言之,您应该能够在那里找到所需的一切。如果这对您来说太复杂了,您可以尝试使用谷歌搜索“select2 knockout custom binding”,看看是否可以找到不太复杂的内容。

引用 Knockout 自定义绑定的概念:http://knockoutjs.com/documentation/custom-bindings.html

祝你好运!

【讨论】:

谢谢 hanes,有没有什么不那么复杂的东西可以建议。我想要做的就是我想使用 select2 和使用 jQuery Ajax 选择多个值,我会将选定的值推送到我的业务层中。我看过你提到的链接。感觉很复杂

以上是关于Knockout.js 与多个 Select2 绑定的主要内容,如果未能解决你的问题,请参考以下文章

使用 Knockout.js 对 Select2 的标记支持

带有自定义模板的 Knockout.Js 中的 Select2

Knockout.js Select2 绑定。将 Select2 升级到 v4 后损坏

使用 knockout.js 和 select2 级联下拉菜单

Knockout/Select2:触发 select2 根据可观察的选项更新进行更新

knockout.js 虚拟模板绑定