将值传递给循环内动态创建的函数调用

时间:2015-09-15 14:43:55

标签: javascript jquery knockout.js

如何设置订阅,以便使用date1更改发生的月份中的相应date1和date2值调用date2Handler

目前,在任何一个月中更改date1值会调用date2Handler,其中“month”最近设置为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)(请参阅month数组的索引)。

如何优雅地修复它?

在实际应用程序中,可能会在页面生命周期内多次弹出和推动月份。

模型

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

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

订阅更改活动

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());
    }
}

1 个答案:

答案 0 :(得分:2)

由于newSubItem.date1.subscribe调用的异步方面,执行时newSubItem实际上是循环的最后一个值。

要解决此问题,您可能需要将此调用包装在一个自执行匿名函数中,以便及时“冻结”您的变量:

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

它应该解决你的问题。