KnockoutJS自定义绑定在绑定期间调用click事件,而不是单击

时间:2013-04-07 17:42:53

标签: javascript knockout.js

我试图使用knockoutjs将一个可观察的数组绑定到两个两列响应式布局和点击事件。

我创建了一个名为TwoCol的自定义绑定,它循环遍历数组,并将节点附加到DOM以创建我建议的布局,但是当我尝试将它们应用于嵌套在自定义绑定中的自定义绑定时,单击事件会给我带来麻烦。循环。

我玩了很多次,遇到了所有类型的结果,但我现在在绑定时调用我的~Click~事件,而不是点击。

http://jsfiddle.net/5SPVm/6/

HTML:

<div data-bind="TwoCol: Friends" id="" style="padding: 20px">

JAVASCRIPT:

function FriendsModel() {
    var self = this;
    this.Friends = ko.observableArray();
    this.SelectedFriend = "";
    this.SetSelected = function (person) {
        alert(person);
        self.SelectedFriend = person;
    }
}
function isOdd(num) {
    return num % 2;
}
ko.bindingHandlers.TwoCol = {
    update: function (elem, valueAccessor) {
        var i = 0;
        var rowDiv;
        var vFriends = ko.utils.unwrapObservable(valueAccessor());
        $(elem).html('');
        while (i < vFriends.length) {
            //create row container every other iteration
            if (!isOdd(i)) {
                rowDiv = document.createElement("div");
                $(rowDiv).addClass("row-fluid");
                elem.appendChild(rowDiv);
            }
            //add column for every iteration
            var colDiv = document.createElement("div");
            $(colDiv).addClass("span6");
            rowDiv.appendChild(colDiv);
            //actual code has fairly complex button html here
            var htmlDiv = document.createElement("div");
            var htmlButton = vFriends[i]
            htmlDiv.innerHTML = htmlButton;
            colDiv.appendChild(htmlDiv);
            //i think i need to add the event to the template too?
            //$(htmlDiv).attr("data-bind", "click: { alert: $data }")
            //it seems that the SetSelected Method is called while looping
            ko.applyBindingsToDescendants(htmlDiv, { click: friends.SetSelected(vFriends[i]) });
            i++;
        }
        return { controlsDescendantBindings: true };
    }
}

var friends = new FriendsModel();
friends.Friends.push('bob');
friends.Friends.push('rob');
friends.Friends.push('mob');
friends.Friends.push('lob');
ko.applyBindings(friends);

1 个答案:

答案 0 :(得分:1)

我认为您没有正确使用ko.applyBindingsToDescendants。我承认我对代码中某些值的含义有点困惑,所以我可能会错误地解释某些内容。

这是一个小提琴,我认为它按照你的意图工作: <删除> http://jsfiddle.net/5SPVm/7/ http://jsfiddle.net/5SPVm/8/

请注意,如果手动控制后代绑定(return { controlsDescendantBindings: true };),则需要在init回调中设置,而不是更新。更新回调为时已晚。

快速删除更改(已编辑)

  1. controlsDescendantBindings移至init绑定回调
  2. 为绑定参数列表添加了必要的参数名称以访问其他值。
  3. 我重新启用了html.attr调用。请注意,现在,由于绑定上下文设置为实际项,因此SetSelected方法不再存在于该级别,因此必须使用$parent.SetSelected

            $(htmlDiv).attr("data-bind", "click: $parent.SetSelected")
    
  4. 修正了ko.applyBindingsToDescendants来电。此方法采用绑定上下文,该上下文是从当前绑定上下文创建的,并且还将元素应用于绑定。你不想重新申请绑定,这就是整个事情需要在init处理程序中的原因。

            var childBindingContext = bindingContext.createChildContext(vFriends[i]);
        ko.applyBindingsToDescendants(childBindingContext, colDiv);