将缺少的项插入到绑定到ko.bindingHandlers.options的数组中



我有以下场景。

示例JavaScript:

function Foo() {
this.id = ko.observable("KEY_1"); //Current selected item
this.list = [{ id: "KEY_2", text: "Two" }, { id: "KEY_3", text: "Three" }]; //All available items
}
ko.applyBindings(new Foo());

这是通过值和选项bindingHandlers的帮助绑定到HTML选择的。

data-bind="value: id, optionsEx: list"

可能当前所选项目未包含在所有可用项目的列表中,因为它已在服务器上删除,不应再被选中。一些由于历史原因,实体仍然将KEY_ 1的值设置为id。我想要的是,如果id的值不再在列表中,那么它应该作为虚拟条目添加到列表中,由客户端上的bindingHandler动态地称为"Deleted"。

我尝试了以下

ko.bindingHandlers["optionsEx"] = {
update: function (element, valueAccessor, allBindingsAccessor) {
var allBindings = allBindingsAccessor(),
optionsValue = allBindings['optionsValue'],
value = ko.utils.unwrapObservable(allBindings['value']),
list;
if (value) {
list = //external function searching the list for the item any adding it if missing
ko.bindingHandlers.options.update(element, function () { return list; }, allBindingsAccessor);
} else {
ko.bindingHandlers.options.update(element, valueAccessor, allBindingsAccessor);
}
}
};

但这行不通。有人能给我一个实现这一目标的提示吗?

更新:我已经创建了一个jsfiddle。它很奇怪,因为代码在jsfiddle中工作,但在我们的开发分支中不工作。我得研究一下原因。但也许有人有更好的想法来实现功能。

http://jsfiddle.net/philipooo/C46A8/

更新:在我看来,bindingHandlers的顺序是至关重要的。也许这解决了我的问题。

我研究了实现这一点的各种方法,并在选项中指定的基本列表中添加了新值(如果不存在)。直接进入小提琴

businessUnitsList: ko.observableArray([{
id: "a",
title: "business1"
}, {
id: "b",
title: "business2"
}, {
id: "c",
title: "business3"
}, {
id: "d",
title: "business4"
}]),

基本列表数组必须是observableArray,这样当添加新值时,它会通过敲除自动更新),然后触发列表刷新。

设置绑定的HTML:

<select data-bind="missingText:'{val} is DELETED',
options:businessUnits.businessUnitsList,
optionsText:'title',
optionsValue:'id', 
value:businessUnits.currentlySelected">
</select>

"missingText"属性挂钩到绑定处理程序,并允许配置文本,以及在文本{val}中未作为令牌找到的值

在绑定处理程序中,我称之为"missingText">

ko.bindingHandlers["missingText"] = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bind) {
var allBindings = allBindingsAccessor(),
items = allBindings['options'],
value = ko.utils.unwrapObservable(allBindings['value']),
valueProperty = ko.utils.unwrapObservable(allBindings['optionsValue']),
textProperty = ko.utils.unwrapObservable(allBindings['optionsText']),
missingTextProperty= ko.utils.unwrapObservable(allBindings['missingText']),
valueSetter = allBindings['value'],
list
//we must have the two properties specified
if (!valueProperty || !textProperty){
throw ("missingText requires the optionsText and optionsValue property to be provided");   
}
if (value) {
//try and find the currentlySelected value in the list
var found = ko.utils.arrayFilter(items(), function (item) {
//we're binding to a particular field for the value
//so look for that as the value
return item[valueProperty] == value;
});
//if we haven't found it in the list, add it with our missingText text
if (found.length === 0) {
var newItem ={};
newItem[valueProperty]=value;
//replace token with the value that's missing
newItem[textProperty]=missingTextProperty.replace('{val}', value);  
//adding the new item to the items list will trigger the list to refresh
//and display our new value                
items.push(newItem);
}

这又是小提琴

希望这能有所帮助?

最新更新