我是淘汰赛的新手,并试图让我的select2与我的淘汰赛绑定很好地配合。
我想要做的就是将帐户数组绑定到我的select2(这个工作)然后 在绑定发生时设置初始值。我出于某种原因不能让这个工作。还注意到init和update函数最初被调用,但是只要我更改select2下拉列表的值,就不会触发更新函数。
任何帮助都将不胜感激。
HTML
<div class="col-sm-12 col-md-3">
<fieldset class="form-group">
<label data-bind="attr:{for:'job'+laborDetailId()}">Job</label>
<select class="select2" data-bind="attr:{id:'job'+laborDetailId()},updateaccountdropdown: {value:account(),data:accounts,width:'100%'}">
</select>
</fieldset>
</div>
JS
var accounts = [{"id":-1,"text":"","description":null}, {"id":25,"text":"J13002","description":null}, {"id":28,"text":"J13053","description":null}];
var LaborListModel = function(laborModels) {
var self = this;
//contains all labor models
self.labordetails = ko.observableArray(laborModels);
self.selectedAccount = ko.observable();
//bindings
ko.bindingHandlers.updateaccountdropdown = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).select2('destroy');
});
var allBindings = allBindingsAccessor(),
select2 = ko.utils.unwrapObservable(allBindings.updateaccountdropdown);
$(element).select2(select2);
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var allBindings = allBindingsAccessor();
if ("value" in allBindings) {
var val = ko.utils.unwrapObservable(valueAccessor());
$(element).val(val.id).trigger('change');
}
}
};
}
getAllLaborDetails().done(function(result) {
loadAccounts().done(function(_accounts) {
accounts = _accounts;
for (var i = 0; i < result.length; i++) {
//LaborModel
var laborDetails = [];
laborDetails.push(new LaborModel(
result[i].labourDetailId,
result[i].account,
result[i].categoryModel,
result[i].description,
result[i].timeStamp,
result[i].hour
));
}
var vm = new LaborListModel(laborDetails);
ko.applyBindings(vm);
});
})
答案 0 :(得分:10)
希望这个“select2”自定义绑定可以帮助您:
ko.bindingHandlers.select2 = {
after: ["options", "value"],
init: function (el, valueAccessor, allBindingsAccessor, viewModel) {
$(el).select2(ko.unwrap(valueAccessor()));
ko.utils.domNodeDisposal.addDisposeCallback(el, function () {
$(el).select2('destroy');
});
},
update: function (el, valueAccessor, allBindingsAccessor, viewModel) {
var allBindings = allBindingsAccessor();
var select2 = $(el).data("select2");
if ("value" in allBindings) {
var newValue = "" + ko.unwrap(allBindings.value);
if ((allBindings.select2.multiple || el.multiple) && newValue.constructor !== Array) {
select2.val([newValue.split(",")]);
}
else {
select2.val([newValue]);
}
}
}
};
$(document).ready(function(){
var data = ko.observableArray([{id: 1, text: "A"}, {id: 2, text: "B"}]);
var value = ko.observable();
ko.applyBindings({data: data, value: value});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/js/select2.full.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/css/select2.css" />
<span>Selected value: </span>
<span data-bind="text: value"></span>
<div style="width: 350px; margin-top: 20px;">
<select style="width: 100%;" data-bind="value: value, valueAllowUnset: true, options: data, optionsText: 'text', optionsValue: 'id', select2: { placeholder: 'Select an option...', allowClear: true }"></select>
</div>
答案 1 :(得分:2)
根据select2 wiki on github的这个示例,他们提供了Knockout binding handler
,它对我有用。
ko.bindingHandlers.select2 = {
init: function (el, valueAccessor, allBindingsAccessor, viewModel) {
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, viewModel) {
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");
}
};
实际上,这是他们提供的原始版本,但我必须更改一行才能选择已选择的选项。
我替换了这一行
$(el).select2("data", converted);
与
$(el).val(converted);
我认为这是因为select2版本存在一些差异 您可以尝试这两种解决方案,看看什么适合您。
Html如下
<select data-bind="selectedOptions: SelectedTags, options: AllTags, valueAllowUnset: true, optionsText:'Text', optionsValue: 'Value',
select2:{ placeholder: 'select tag', allowClear: true, multiple:'multiple'}" multiple></select>
更新对于select2版本4 ,以前的解决方案适用于版本4以下的select2
版本。对于Select2版本4,我已经创建了一些其他binding handler
{{3 }}