24

我有一个淘汰绑定处理程序,它使用 plupload 进行拖放和 ajax 上传。

为了使用 plupload 脚本,我创建了一个 plupload 实例,该实例又将事件侦听器绑定到 DOM 元素。

这很好用。

但是,我有一个“文件夹”列表,当我单击一个文件夹时,我会显示该文件夹中的文件列表。我通过使用 foreach 绑定 selectedFolder().documents 来重用相同的 DOM 元素。

我遇到的问题是,在我的绑定处理程序中,我在 init 函数中完成了所有的 plupload 工作,并且由于我重用了 DOM 元素,它们获得了多个绑定到它们的事件处理程序。这会导致将拖放事件发送到所有处理程序。这意味着,如果我将文件拖放到渲染文件列表中,则 drop 事件也会在所有先前渲染的文件列表上触发。

我正在寻找的是绑定处理程序中的某种拆卸或清理功能,这样我就可以在文件列表未呈现时取消注册所有事件(这是一个词吗?)。

也许我们无法检测到未渲染?那我该如何处理呢?我不希望有一个全局实例,因为这会阻止我同时在多个地方使用绑定。

很抱歉没有给你任何代码。我在我的手机自动取款机上。

干杯!

4

2 回答 2

32

您可以注册一个处理程序,该处理程序将在 KO 删除元素时执行(例如重新渲染模板时)。看起来像:

    //handle disposal (if KO removes by the template binding)
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
        $(element).datepicker("destroy");
    });

因此,在您的“init”函数中,您将为被绑定的元素注册一个 dispose 回调,并且您将有机会运行您想要的任何清理代码。

于 2012-04-25T22:21:00.323 回答
3

我相信这里提供的解决方案只有在 Knockout 是删除 DOM 节点(即当它重新设置模板时)时才有效。我很难让它在某些条件下触发。在某些情况下,无论您的元素如何被删除,您都需要执行回调;无论是使用 Knockout,还是通过 jQuery.html() 等(尤其是在单页应用程序中)。

在 jQuery 的帮助下,我酝酿了一种不同的方法来添加这样的钩子。使用特殊事件 API(在此处进行了详细描述),您可以添加一个在从 DOM 节点移除特定事件时执行的方法(在拆卸时发生的事情)。

如果您将 Knockout 与 jQuery 结合使用,则可以将其包装到敲除绑定中,如下所示:

ko.bindingHandlers.unload = {
    init: function (element, valueAccessor) {
        var eventName = 'your_unique_unLoad_event'; // Make sure this name does not collide
        if (!$.event.special[eventName]) {
            $.event.special[eventName] = {
                remove: function (o) {
                    o.data.onUnload()
                }
            };
        }
        $(element).on(eventName, { onUnload: valueAccessor()}, $.noop);
    }
};

然后,您可以在任何元素上使用它,如下所示:

<div id="withViewModelMethod" data-bind="unload: aMethodOnMyViewModel" />
<div id="withInLineMethod" data-bind="unload: function() { /* ... */ }" />

我欠这篇SO 帖子的功劳。

于 2013-01-23T20:00:17.523 回答