Knockout点击绑定以在可观察的更改上调用切换事件

时间:2014-02-04 20:30:50

标签: javascript jquery twitter-bootstrap knockout.js

我正在用ajax加载一个空的ko.observablearray。该数组绑定到foreach模板以显示按钮组。通过检查特定值是否在ko.observablearray中,按钮被设置为活动/非活动状态,并且在单击按钮时,它会从数组中推送或删除该值。

问题是:当我加载ajax数据时,它会填充数组,选择按钮......然后它会启动click事件,最终会反转选择。因此,如果星期日应该被选中而星期一不被选中,那么我星期天没有被选中并且星期一被选中。

除了数组反转之外,这些函数还可以实现预期的功能。

我似乎想到解决此问题的唯一方法是在第一次活动检查期间附加click事件,或者预先反转我的数组。这两种方式都不是很干净。

有没有办法绕过初始点击事件?或者一种不会导致初始切换的映射方式?

<div class="tab-content" data-bind="foreach: schedulesModel.scheduleViewModel">
<div id="day_group" class="btn-group" data-toggle="buttons-checkbox">
    <button type="button" class="btn btn-primary" data-bind="css: {active: $parent.schedulesModel.isSelected($index,'SUN')}, click: $parent.schedulesModel.selectButton($index,'SUN')">Sunday</button>
    <button type="button" class="btn btn-primary" data-bind="css: {active: $parent.schedulesModel.isSelected($index,'MON')}, click: $parent.schedulesModel.selectButton($index,'MON')">Monday</button>
    <button type="button" class="btn btn-primary" data-bind="css: {active: $parent.schedulesModel.isSelected($index,'TUE')}, click: $parent.schedulesModel.selectButton($index,'TUE')">Tuesday</button>
    <button type="button" class="btn btn-primary" data-bind="css: {active: $parent.schedulesModel.isSelected($index,'WED')}, click: $parent.schedulesModel.selectButton($index,'WED')">Wednesday</button>
    <button type="button" class="btn btn-primary" data-bind="css: {active: $parent.schedulesModel.isSelected($index,'THU')}, click: $parent.schedulesModel.selectButton($index,'THU')">Thursday</button>
    <button type="button" class="btn btn-primary" data-bind="css: {active: $parent.schedulesModel.isSelected($index,'FRI')}, click: $parent.schedulesModel.selectButton($index,'FRI')">Friday</button>
    <button type="button" class="btn btn-primary" data-bind="css: {active: $parent.schedulesModel.isSelected($index,'SAT')}, click: $parent.schedulesModel.selectButton($index,'SAT')">Saturday</button>
</div>

    var schedulesModel = function SchedulesModel() {
    var self = this;
    var numZones = 8;
    this.selectButton = function (index, object) {
        var obj = object;
        var idx = this.scheduleViewModel()[index()].schedule.data.days.indexOf(obj);
        if (idx >= 0) {
            this.scheduleViewModel()[index()].schedule.data.days.remove(obj);
            console.log("object: " + obj + " removed");
        } else {
            this.scheduleViewModel()[index()].schedule.data.days.push(obj);
            console.log("object: " + obj + " added");
        }
    };
    this.isSelected = function (index, object) {
        var obj = object;
        var idx = this.scheduleViewModel()[index()].schedule.data.days.indexOf(obj);
        if (idx >= 0) {
            console.log("object: " + obj + " found");
            return true;

        }
        console.log("object: " + obj + " not found");
        return false;
    };
    var mapping = {};
    this.scheduleViewModel = ko.mapping.fromJS([]);
    this.updateModel = function (model) {
        ko.mapping.fromJS(model, mapping, self.scheduleViewModel);
    };
    $.ajax({
        type: 'POST',
        url: '/echo/json/',
        data: {
            JSON.stringify(
            [{
            schedule: {
                data: {
                    days: ["MON","TUE","FRI","SAT","SUN"]
                }}}])
        },
        context: this,
        dataType: 'json'
        success: function (data) {
            self.updateModel(data);
        }
    });

};
ko.applyBindings(new schedulesModel());

1 个答案:

答案 0 :(得分:0)

<button type="button" class="btn btn-primary" data-bind="css: {active: $parent.schedulesModel.isSelected($index,'SUN')}, click: $parent.schedulesModel.selectButton($index,'SUN')">Sunday</button>

问题在于,您实际上是在绑定中调用 selectButton并将click设置为调用的结果而不是设置它到selectButton函数本身。

解决此问题的一种方法是用

替换绑定
click: $parent.schedulesModel.selectButton.bind(null,$index,'SUN')

(显然你必须为所有星期绑定做到这一点)