使用Knockout JS进行JQuery UI Multiselect - 使用帮助程序插件进行数据绑定

时间:2016-02-25 07:59:25

标签: knockout.js jquery-ui-multiselect

我正在尝试使用KnockoutJS绑定实现jQuery UI Multiselect。我想这不可能是原生的,这就是this plugin的原因。

我正在使用该插件。我在PHP代码中创建我的多选,但输出html是这样的:

<select id="multiselectpoc" data-bind="multiselect  : { config : multiSelectConfig,
            options: _categories,
            optionsText: '_name',
            optionsValue: '_id',
            value: selectedCategory,
            optionsCaption: 'CATEGORY'}" title="Basic example" multiple="multiple" name="example-basic" size="5" style="display: none;">
        </select>

我知道在php中创建它不是问题,因为我在php中创建了不是jqueryUI Multiselects的其他<select>,并且它们的数据绑定有效。

这是我的视图模型(我使用的是typescript):

class SearchFilterViewModel {
    multiSelectConfig = {};
    _countriesList = [];
    _regionsList = [];
    _countries = ko.observableArray();
    _regions = ko.observableArray();
    _categories = ko.observableArray([
        new Category(name="Meat-Free Meat", 1),
        new Category(name="Dairy-Free Dairy", 2),
        new Category(name="Confectionery", 3),
        new Category(name="Baking", 4),
        new Category(name="Dessert", 5)
    ]);
    selectedCountry = ko.observable();
    selectedCity:  KnockoutObservable<string> = ko.observable('');
    selectedCategory:  KnockoutObservable<string> = ko.observable('');

    constructor(allCountries) {
        for (var index = 0; index < allCountries.length; index++) {
            this._countriesList.push(allCountries[index]);
        }
        this._countries(this._countriesList);
        this.selectedCountry.subscribe(this.updateCities.bind(this))
    }

    updateCities(geonameId) {
        var self = this;
        self._regionsList = [];
        $.ajax({
            url: `http://api.geonames.org/children?geonameId=${geonameId}&username=elion`
        }).then(function(allCitiesXML) {
            var allCitiesJSON = xml2json(allCitiesXML);
            var allCities = JSON.parse(allCitiesJSON);
            for (var index = 1; index < allCities.geonames.length - 1; index++) {
                self._regionsList.push(allCities.geonames[index].geoname);
            }
            self._regions(self._regionsList);
            });
    }
}

class Category {
    _name:  KnockoutObservable<string>;
    _id:    KnockoutObservable<number>;

    constructor(name, id) {
        this._name = ko.observable(name);
        this._id = ko.observable(id);
    }
}



$(document).ready(function() {
    var _searchFilterViewModel: SearchFilterViewModel = new SearchFilterViewModel(allCountries);
    var _searchFilterForm = $("#find-vegan-products-page").find("form")[0];
    ko.applyBindings(_searchFilterViewModel, _searchFilterForm);
    $('.select-multiple').each(function(i, obj) {
        //obj[i] gets each element inside the div
        $(this).multiselect();
    })
});

这个问题主要是关于如何在viewmodel中配置空multiSelectConfig对象。当我在Web浏览器中运行页面时,<select>中的输出html现在是许多<li>个标签,其中包含一些jquery ui多选代码,但重要的是每个内部{ {1}} <option></option>位于每个<span>[object Object]</span>标记内。 <li>标签的数量与类别相同,这让我觉得数据绑定正常。我只需要点击[object object]来获取属性(category.name)。我该怎么做?

2 个答案:

答案 0 :(得分:0)

您应该浏览KnockoutJS教程。 AFAICT您目前还没有真正使用它。

绑定处理程序负责调用DOM上的multiselect(...)。你不应该像现在这样自己打电话。相反,您需要一个将所有信息传递给自定义绑定处理程序的视图模型。

绑定处理程序需要config作为输入,并且您的视图告诉它您的视图模型具有包含该信息的multiSelectConfig属性。绑定处理程序可能崩溃,因为您的视图模型缺少该属性。

换句话说,您所拥有的绑定处理程序假定您的视图模型具有名为的

  • multiSelectConfig
  • _categories,每个<{1}}和_name属性
  • _id

您还没有显示您的视图模型代码或KO引导代码,但您需要这样才能让事情运行起来。例如:

selectedCategory

这段代码浏览了很多重要的概念,例如:视图模型,可观察数组,将json映射到视图模型等的构造函数,所以我再次建议查看KO网站及其教程。

答案 1 :(得分:0)

由于我的css,这是使用bootstrap设计的,这不需要它,也没有任何依赖。

<div class="input-group-lg input-group-xl">
     <select class="form-control needsclick" data-bind="options: ovariesJSON, selectedOptions: RightOvaryIDs, optionsText: 'Name', optionsValue: 'ID', optionsCaption: 'Select'" multiple="true"></select>
</div>

参考:http://knockoutjs.com/documentation/selectedOptions-binding.html

他们的例子:

<p>
    Choose some countries you'd like to visit: 
    <select data-bind="options: availableCountries, selectedOptions: chosenCountries" size="5" multiple="true"></select>
</p>

<script type="text/javascript">
    var viewModel = {
        availableCountries : ko.observableArray(['France', 'Germany', 'Spain']),
        chosenCountries : ko.observableArray(['Germany']) // Initially, only Germany is selected
    };

    // ... then later ...
    viewModel.chosenCountries.push('France'); // Now France is selected too
</script>