可观察的通知父ObservableArray

时间:2013-11-01 16:33:48

标签: knockout.js

我有一个observableArray fieldChoices,其中包含以下类似的可观察对象:{ name: ko.observable('new choice') }

我想让Observables通知必须通知另一个计算机的ObservableArray。

我这样绑定他们:

 <div data-bind="foreach: $parent.fieldChoices">
     <div>
        <i class="icon-caret-right"></i>
        <input type="text" class="span8" data-bind="value: name(), test: name()" />
        <i class="icon-arrow-up" data-bind="click: $parentContext.$parent.shiftChoiceUp, visible: $index() !== 0"></i>
        <i class="icon-arrow-down" data-bind="click: $parentContext.$parent.shiftChoiceDown, visible: $index() !== ($parentContext.$parent.fieldChoices().length - 1)"></i>
        <i class="icon-remove" data-bind="click: $parentContext.$parent.removeChoice, visible: $parentContext.$parent.fieldChoices().length > 2"></i>
     </div>
</div>

name值发生变化时,我无法让observable通知可观察数组。我尝试添加自定义绑定test: name()并从那里通知。问题是当值改变时不会更新绑定。

我怎样才能使这个工作?

编辑:即使有类似的问题,我也试图通过自定义绑定来解决这个问题。我无法找到这种方法的任何解决方案。

2 个答案:

答案 0 :(得分:1)

这个问题对我来说没有多大意义,因为默认情况下你所描述的是有效的(当值发生变化时,可观察者会通知他们的订阅者)。您可以为您的observable创建一个扩展器,如果您愿意,可以显式地通知您的observableArray,但您可能不希望通知observableArray observable已更改(因为它不会通知任何其他人,因为它是 value 尚未更改)您可能只想做一些常用功能 -

创建一个可观察的数组 -

var myArray = ko.observableArray();

注册扩展程序 -

ko.extenders.trackChildChanges = function (target, value) {
    target.subscribe(function () {
        // Do some notification
    });
    return target;
};

然后创建你的observable并扩展它们 -

function child(object) {
    var self = this;
    self.Id = ko.observable(id).extend({trackChildChanges: true});
    self.Name = ko.observable(name)extend({trackChildChanges: true});
}

var regArray = [{ id: 1, name: 'Bill'}, {id: 2, name: 'John'}];

$.each(regArray, function(index, item) {
    myArray.push(new child(item));
});

答案 1 :(得分:0)

您的fieldChoices(可观察数组)会在项目添加并从数组中获取时更新,而不是在项目更改值时更新。我建议你订阅数组中的每个项目。

var thingsToDoWhenAnItemsNamePropertyChanges = function(NewValue){
    alert('An items name property change to '+NewValue);
}
var arr = fieldChoices();
for(var i=0, cnt=arr.length;i<cnt;i++){
   var item = arr[i];
   var nm = item && item.name;
   if(typeof(nm.subscribe) === 'function')nm.subscribe(thingsToDoWhenAnItemsNamePropertyChanges);
}

或者,如果您在将项目加载到fieldChoices中时已遍历项目,则可以订阅每个对象名称属性。