1

我有以下情况。

示例 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-select。

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

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

我尝试了以下

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/philipoo/C46A8/

更新:正如我所见,bindingHandlers 的顺序是关键任务。也许这解决了我的问题。

4

1 回答 1

1

我查看了执行此操作的各种方法,并想出了将新值添加到选项中指定的基本列表(如果它不存在)。 直接上小提琴

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);

        }

这又是小提琴

希望这有帮助吗?

于 2014-01-18T10:27:52.470 回答