1

我正在尝试使用 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);
4

1 回答 1

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);
    
于 2013-04-07T18:25:54.040 回答