【问题标题】:Why is this event being handled twice in knockout?为什么这个事件在淘汰赛中被处理了两次?
【发布时间】:2014-03-18 19:33:43
【问题描述】:

由于某种原因,下面的代码使链接的点击事件触发了两次。我对淘汰赛比较陌生,我想我可能做错了我的自定义绑定。谁能告诉我我做错了什么? (顺便说一句,我没有发布小提琴的原因是我无法在 jsfiddle 上包含来自 github 的映射插件。)

JS:

ko.bindingHandlers.activityContent = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        // This will be called when the binding is first applied to an element
        // Set up any initial state, event handlers, etc. here
        var content = document.createElement("p");
        content.innerHTML = '<a href="javascript:void(0)" data-bind="text: user_name, click: $parent.NavigatePage.bind($data, \'profile\', user_id)"></a>';
        element.appendChild(content);
        ko.applyBindings(bindingContext, content);
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        // This will be called once when the binding is first applied to an element,
        // and again whenever the associated observable changes value.
        // Update the DOM element based on the supplied values here.
    }
};

var activities = ko.mapping.fromJS({Activities: [{
    "user_id": "52b5042d572b94ceadf6asdf1a2a5bc",
    "user_name": "Sean Templeton"
}, {
    "user_id": "52b5042d57asfda2b94ce61a2a5bc",
    "user_name": "Sean Templeton"
}, {
    "user_id": "52b5042d572b94ce61a2a5bc",
    "user_name": "Sean Templeton"
}, {
    "user_id": "52b5042d5asdfasdf72b94ce61a2a5bc",
    "user_name": "Sean Templeton"
}, {
    "user_id": "52basdf5042d572b94ce6asdf1a2a5bc",
    "user_name": "Sean Templeton"
}], NavigatePage: function(page, userId) { console.log(this); console.log(page); console.log(userId()); }});

ko.applyBindings(activities);

html:

<Ul data-bind="foreach: Activities">
    <li data-bind="activityContent: $data"></li>
</ul>

【问题讨论】:

  • 您使用的是哪个版本的 KO?为什么将 html 放在处理程序中?为什么不直接内联或使用单独的模板 (jsfiddle.net/eTXQJ)?
  • 因为innerHTML是动态的,而且Knockout v3.x
  • 你确定是KO版吗?因为您的代码会抛出“消息:您不能将绑定多次应用于同一元素。”使用 KO3.0 时出错 jsfiddle.net/hLpzB 如果我只使用一些非常旧的 KO 版本,如 2.2.1,那么我可以重现这种双击行为...
  • 是的,抱歉,对于 KO.3.x,您需要停止在父级上绑定才能正常工作

标签: knockout.js custom-binding


【解决方案1】:

删除init 中的ko.applyBindings(bindingContext, content); 行,并记住update 在初始化时运行一次,然后在每次更新时运行。

另外,你有一个更大的问题。在@nemesv 上面给出的小提琴中,通过不从自定义绑定中删除ko.applyBindings(),该列表甚至没有被完整地迭代5次。

不同的方法

除非您对本示例之外的 activityContent 绑定有很好的计划,否则您可以放弃自定义绑定,只需在 viewModel 中的 &lt;li&gt; 元素上注册一个委托事件。然后您可以使用 Knockout 的ko.dataFor() 来确定点击了什么,然后调用 NavigatePage()。这种方法的性能要高得多,并且不需要自定义绑定。

您可以阅读有关委托事件here

【讨论】:

  • 问题是我们尽可能不使用 jQuery,因为我们正在将它完全从我们的应用程序中逐步淘汰。此外,这会破坏我们的应用程序流程,因为 html 元素的唯一位置是在我们的模板/视图中。
  • 不过这看起来很有趣,也许以后可以找到另一种类似的方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多