首页 文章

Knockout绑定选择动态可观察数组

提问于
浏览
0

我有动态绑定问题使用knockout选择控件 . 我想要实现的是一段代码,它将observableArray的可观察对象绑定到select选项 . observableArray中的'objects'不断变化 .

存储在observableArray中的对象,我们称之为sampleObj,有一些属性(ko.observables),如name,lastName和phoneNumber . 我想显示observableArray中存储的所有对象的选项选项lastNames .

我对cshtml中的observable的绑定如下所示:

<select data-bind="options: sampleObservableArray, optionsText: lastName, optionsCaption: 'choose...'"></select>

除了'选择...'文本之外,它不会显示任何内容 . sampleObservableArray的内容在js中更新,我可以随时使用console.log它 . 我绑定值的方式有什么不对,或者我应该以某种方式强制刷新select控件?当然作为一个完整的业余爱好者,我试过我认为使用和不使用parethnesis的所有可能组合:)但仍然没有效果 .

sampleObservableArray - 包含sampleObj的ko.observableArray

sampleObj - ko.observable,带有一些属性,如name,lastName和phoneNumber,其中所有属性都是ko.observables .

EDIT: 回答@ Tomalak的问题,有一个代码可以更清晰 . 首先,sampleObj模型:

define('sampleObj',
['ko'],
function (ko) {
    var
        SampleObj = function () {
            var self = this;
            self.name = ko.observable();
            self.lastName = ko.observable();
            self.phoneNumber = ko.observable();
            return self;
        };

    return SampleObj;
});

然后将sampleObj对象添加到observableArray:

// newData is an argument of a function triggered by signalR action, and returns strings as its properties
var sampleObj = ko.observable(new SampleObj()
    .name(newData.name)
    .lastName(newData.lastName)
    .phoneNumber(newData.phoneNumber);

var sampleObjEntry = ko.utils.arrayFirst(sampleObservableArray(), function (item) {
    return item().phoneNumber() === newData.phoneNumber;
});
// if object with the phoneNumber already exits replace it, if not - add
if (!sampleObjEntry) {
    sampleObservableArray.push(sampleObj);
} else {
    sampleObservableArray()[sampleObservableArray().indexOf(sampleObjEntry)] = sampleObj;
    sampleObservableArray.valueHasMutated();
}

不知道它是否有帮助 .

1 回答

  • 0

    我创建了简单的JSFiddle Demo *,它按预期工作 .
    我认为你的代码中的问题是符合的

    sampleObservableArray()[sampleObservableArray().indexOf(sampleObjEntry)] = sampleObj;
    

    您应该从数组中删除 sampleObjEntry ,然后按 sampleObj 或更新已存在的 sampleObjEntry .

    例如:

    ...
    else {
        sampleObjEntry.name(newData.name);
        sampleObjEntry.lastName(newData.lastName);
        sampleObjEntry.phoneNumber(newData.phoneNumber);
    }
    

    要么

    ....
    else {
        sampleObservableArray.remove(sampleObjEntry);
        sampleObservableArray.push(sampleObj);
    }
    
    • JSFiddle演示源

    Javascript

    function Person(name, lastName, phone)
    {
        return {
            name : ko.observable(name),
            lastName : ko.observable(lastName),
            phoneNumber : ko.observable(phone)
        }
    }
    
    var vm = {
        sampleObservableArray : ko.observableArray(),
        addPerson : function()
        {
           var newPhone = document.getElementById("_phone").value,
               newName = document.getElementById("_name").value,
               newLastName = document.getElementById("_lastName").value;
           var existentPerson = ko.utils.arrayFirst(vm.sampleObservableArray(), function(item)
                                                    {
                                                        return item.phoneNumber() == newPhone;
                                                    })
           if (existentPerson)
           {
               existentPerson.name(newName);
               existentPerson.lastName(newLastName);
               existentPerson.phoneNumber(newPhone);
           }
           else
           {
               vm.sampleObservableArray.push(new Person(newName, newLastName, newPhone))
           }
    
    
        }
    }
    
    vm.sampleObservableArray.push(new Person("Ronald", "McDonald", "1"))
    vm.sampleObservableArray.push(new Person("Michael", "McConnel", "2"))
    
    ko.applyBindings(vm)
    

    Html

    <select data-bind="options: sampleObservableArray, optionsText: 'lastName', optionsCaption: 'choose...'"></select>  
    
    <label for="_name">Name:</label><input id="_name"/>
    <label for="_lastName">Last Name:</label><input id="_lastName"/>
    <label for="_phone">Phone:</label><input id="_phone"/>
    <button data-bind="click: addPerson">Add person</button>

相关问题