2015-05-12 2 views
2

У меня есть большой нокаут ViewModel которого это является JSON представление:Подписаться на изменения в промежуточных объектов в knockoutjs ViewModel

... 
existingPlans: { 
    startDate: "2014-11-01", 
    endDate: "2017-03-01", 
    plans: [ 
     { 
      "customTitle": "plan 1 name", 
      "monthlyPayments": [ 15000, 15000, 15000, 15000, 15000, 15000 ], 
      "futureBalance": [ 90000, 75000, 60000, 45000, 30000, 15000 ] 
     }, 
     { 
      "customTitle": "plan 2 name", 
      "monthlyPayments": [ 7000, 7000, 7000, 7000 ], 
      "futureBalance": [ 28000, 21000, 14000, 7000 ] 
     } 
    ] 
} 
... 

StartDate и ENDDATE являются наблюдаемыми и планы является observableArray. Что бы я хотел сделать, это создать одну привязку, которая срабатывает, когда любой из этих трех наблюдаемых изменяется так на уровне «existingPlans».

Я мог бы сделать вычисленное поле, которое зависит от всех трех, но разве нет более простого способа сделать это?

Что-то вроде примера ниже не работает, так как existingPlans сама не может быть наблюдаемым (правильно?)

viewModel.existingPlans.subscribe(function(newValue) { 
    // do stuff with newValue.startDate(), etc 
}) 

ответ

1

Это зависит от того, что должно произойти при изменении этих свойств. Если вы просто хотите, чтобы вызвать событие или что-то подобное можно было подписаться на свойства и использовать тот же обработчик подписки для них, как этот

function ExistingPlans() { 
    this.startDate = ko.observable(); 
    this.endDate = ko.observable(); 
    this.plans = ko.observableArray(); 

    this.startDate.subscribe(this.handleChange, this); 
    this.endDate.subscribe(this.handleChange, this); 
    this.plants.subscribe(this.handleChange, this);      
} 

ExistingPlans.prototype.handleChange = function() { 
    // do stuff 
}; 

Если вам нужно вычислить что-то или представить какой-то результат от значения из свойства Я бы создал вычисляемый наблюдаемый.

+0

Хорошо, так что в любом случае мне придется проходить через наблюдаемых детей? Привязка к чему-то более высокому дереву JSON не является вариантом? – koenpeters

+0

Возможно, я неправильно понял ваш вопрос. Если сущность ExistingPlans существует в родительской модели просмотра, вы можете подписаться на свойства аналогичным образом, например, 'this.existinPlans.startDate.subscribe (this.handleChange, this)' и вместо этого добавить метод handleChange в родительскую модель. – lagerone

+1

Вы не можете просто наблюдать за корневым объектом, потому что нокаут наблюдает за изменениями ссылок, поэтому, даже если вы изменяете дочерние объекты, ссылка остается прежней, поэтому вам нужно добавить подписчиков на все дочерние элементы, как указано выше – Luis

0

Поскольку вы имеете дело с тремя различными наблюдаемыми, вы не можете использовать ручную подписку. Вычислимый наблюдаемый способ пойти. Вычисляемый наблюдаемым автоматически следит за все наблюдаемые вам доступ, и так будет просто работать:

ko.computed(function() { 
    // do stuff with existingPlans.startDate(), etc 
}); 

Если вы хотите, чтобы полностью убедиться, что вы подписаны на все наблюдаемых в модели представления, вы можете использовать ko.toJS:

ko.computed(function() { 
    ko.toJS(existingPlans); 
    // do stuff with existingPlans.startDate(), etc 
}); 
Смежные вопросы