JQuery UI 使用 Knockout JS 进行多选 - 使用辅助插件进行数据绑定
JQuery UI Multiselect with Knockout JS - data-binding with a helper plugin
我正在尝试实施 jQuery UI Multiselect with a KnockoutJS binding. I guess it cannot be done natively, which is why 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 中创建的其他 <select>
不是 jqueryUI多选,它们的数据绑定有效。
这是我的视图模型(我使用打字稿):
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
对象。当我在网络浏览器中 运行 页面时, <select>
中的输出 html 现在是许多 <li>
标签,其中包含相当多的 jquery ui 多选代码,但重要的是每个 <option></option>
内部是 <span>[object Object]</span>
,它位于每个 <li>
标记内。 <li>
标签的数量与类别相同,这让我觉得数据绑定有效。我只需要点击 [object object] 来获取属性 (category.name)。我该怎么做?
您可能应该 运行 完成 KnockoutJS 教程。 AFAICT 你目前并没有真正使用它。
绑定处理程序负责在您的 DOM 上调用 multiselect(...)
。你不应该像现在这样自己调用它。相反,您需要一个将所有信息传递给自定义绑定处理程序的视图模型。
绑定处理程序需要一个 config
作为输入,并且您的视图告诉它您的视图模型有一个包含该信息的 multiSelectConfig
属性。绑定处理程序可能会崩溃,因为您的视图模型缺少 属性.
换句话说,您拥有的绑定处理程序假定您的视图模型具有名为的可观察对象(或至少属性):
multiSelectConfig
_categories
每个 _name
和 _id
属性
selectedCategory
您还没有显示您的视图模型代码或 KO 引导代码,但您需要它来获取东西 运行ning。例如:
$(function(){
var vm = {
multiSelectConfig: { /* config here */ },
_categories: [{_id: 1, _name: "test"},
selectedCategory: ko.observable()
};
ko.applyBindings(vm);
});
这段代码浏览了很多重要的概念,例如视图模型的构造函数、可观察数组、将 json 映射到视图模型等,因此我再次建议您查看 KO 网站及其教程。
由于我的 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>
我正在尝试实施 jQuery UI Multiselect with a KnockoutJS binding. I guess it cannot be done natively, which is why 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 中创建的其他 <select>
不是 jqueryUI多选,它们的数据绑定有效。
这是我的视图模型(我使用打字稿):
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
对象。当我在网络浏览器中 运行 页面时, <select>
中的输出 html 现在是许多 <li>
标签,其中包含相当多的 jquery ui 多选代码,但重要的是每个 <option></option>
内部是 <span>[object Object]</span>
,它位于每个 <li>
标记内。 <li>
标签的数量与类别相同,这让我觉得数据绑定有效。我只需要点击 [object object] 来获取属性 (category.name)。我该怎么做?
您可能应该 运行 完成 KnockoutJS 教程。 AFAICT 你目前并没有真正使用它。
绑定处理程序负责在您的 DOM 上调用 multiselect(...)
。你不应该像现在这样自己调用它。相反,您需要一个将所有信息传递给自定义绑定处理程序的视图模型。
绑定处理程序需要一个 config
作为输入,并且您的视图告诉它您的视图模型有一个包含该信息的 multiSelectConfig
属性。绑定处理程序可能会崩溃,因为您的视图模型缺少 属性.
换句话说,您拥有的绑定处理程序假定您的视图模型具有名为的可观察对象(或至少属性):
multiSelectConfig
_categories
每个_name
和_id
属性selectedCategory
您还没有显示您的视图模型代码或 KO 引导代码,但您需要它来获取东西 运行ning。例如:
$(function(){
var vm = {
multiSelectConfig: { /* config here */ },
_categories: [{_id: 1, _name: "test"},
selectedCategory: ko.observable()
};
ko.applyBindings(vm);
});
这段代码浏览了很多重要的概念,例如视图模型的构造函数、可观察数组、将 json 映射到视图模型等,因此我再次建议您查看 KO 网站及其教程。
由于我的 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>