2015-09-15 4 views
2

Как установить подписку, чтобы вызвать date2Handler с соответствующими значениями date1 и date2 с месяца, в котором произошло изменение даты1?Передача значений динамически созданному вызову функции внутри цикла

В настоящее время изменение даты1 в любой день вызывает дату2Handler с «месяцем», который был установлен на newSubItem совсем недавно. В приведенном ниже примере функция, инициированная по подписке на dataViewModel.agenda.months[0].date1, фактически вызывает data2Handler(dataViewModel.agenda.months[2].date1, dataViewModel.agenda.months[2].date2) вместо data2Handler(dataViewModel.agenda.months[0].date1, dataViewModel.agenda.months[0].date2) (см. Индексы массива месяцев).

Как элегантно исправить?

В реальном приложении месяцы могут быть вытолкнуты и динамически выдвинуты несколько раз за время жизни страницы.

Модель

var dataModel = { 
    months: [], 
    agenda: { 
     months: [], 
    }, 
}; 

var observableModel = ko.mapping.fromJS(dataModel); 
ko.applyBindings(observableModel, document.getElementById("rootView")); 

Subcribing изменить событие

for (var i = 0; i < 3; i++) { 
    dataViewModel.months.push(ko.mapping.fromJS({ 
     monthId: null 
    })); 
    var newSubItem = ko.mapping.fromJS({ 
     date1: null, 
     date2: null 
    }); 
    newSubItem.date1.subscribe(function() { 
     date2Handler(newSubItem.date1, newSubItem.date2) 
    }); 
    dataViewModel.agenda.months.push(newSubItem); 
} 

function date2Handler(date1, date2) { 
    if (date2() == null) { 
     date2(date1()); 
    } 
} 

ответ

2

Из-за асинхронный аспект вашей newSubItem.date1.subscribe вызова, когда выполняется, newSubItem фактически последнее значение вашего цикла.

Чтобы исправить это, возможно, потребуется, чтобы обернуть этот вызов в себя исполняющим анонимную функцию «заморозить» ваш переменной во времени:

(function (item) { 
    newSubItem.date1.subscribe(function() { 
     date2Handler(item.date1, item.date2) 
    }); 
}(newSubItem)); 

Это должно устранить проблему.

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