2013-11-01 3 views
0

У меня есть observableArray fieldChoices, который содержит наблюдаемые как следующие: { name: ko.observable('new choice') }Наблюдаемые уведомляет родителя ObservableArray

Я хочу, чтобы получить Наблюдаемые уведомить 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 значение изменяется. Я попытался добавить пользовательскую привязку test: name() и известить оттуда. Проблема в том, что привязка не обновляется при изменении значения.

Как я могу заставить это работать?

EDIT: Несмотря на то, что есть подобные вопросы, я пытаюсь решить эту проблему с помощью специального связывания. Я не смог найти решения для этого подхода.

ответ

1

Этот вопрос не имеет для меня тонкости, потому что по умолчанию вы описываете работы (наблюдаемые уведомляют своих подписчиков о изменении значений). Вы можете создать расширитель для своих наблюдаемых, которые явно укажут ваш наблюдаемый массив, если вы хотите, но вы, вероятно, не хотите уведомлять наблюдаемый массив о том, что наблюдаемое изменено (потому что тогда оно не будет уведомлять кого-либо еще, потому что это значение hasn «т изменилось), вы, вероятно, просто хотите сделать некоторые общие функции -

Создать наблюдаемый массив -

var myArray = ko.observableArray(); 

зарегистрировать расширитель -

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

А затем создать наблюдаемый и расширить их -

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)); 
}); 
+0

Моя основная цель - получить «вычисленный» для переоценки при изменении значения наблюдаемого. Я подумал, что есть способ получить подписку, когда значение изменяется в пользовательской привязке и оттуда, чтобы заставить «вычисленный» переоценить. Но я дам ему возможность использовать удлинители, потому что я должен его решить. – razvanz

+0

@razvan Все, что вам нужно сделать, это просто создать функцию write: на вычисленном и записать на нее из этого расширителя ... –

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, то вы можете подписаться на каждый объект имя свойства затем.

Смежные вопросы