2012-04-25 3 views
24

У меня есть обработчик привязки нокаута, который использует plupload для перетаскивания и загрузки ajax.Функция разблокировки дескриптора нокаута?

Чтобы использовать скрипт plupload, я создаю экземпляр plupload, который, в свою очередь, связывает прослушиватели событий с элементами DOM.

Это хорошо работает.

Однако у меня есть список «папок», и когда я нажимаю папку, я показываю список файлов в этой папке. Я повторно использую те же элементы DOM для этого, связывая selectedFolder() с документами, использующими foreach.

Проблема у меня в том, что в моем обработчике привязки я делаю все свои файлы plupload в функции init, и, поскольку я повторно использую элементы DOM, они получают несколько обработчиков событий, связанных с ними. Это приводит к тому, что события перетаскивания передаются всем обработчикам. Это означает, что если я удаляю файл в списке отображаемых файлов, событие drop также запускается во все ранее отображенные списки файлов.

Что я ищу - это какая-то функция разрывания или очистки в обработчике привязки, чтобы я мог отменить регистрацию всех событий всякий раз, когда список файлов становится незанятым (это слово?).

Возможно, мы не можем обнаружить отказ? Как бы я тогда справился с этим? Я бы предпочел не иметь глобальный экземпляр, так как это помешало бы мне использовать привязку в нескольких местах одновременно.

Извините, что вы не указали какой-либо код. Я нахожусь на мобильном телефоне.

Cheers!

ответ

32

Вы можете зарегистрировать обработчик, который будет выполняться всякий раз, когда KO удаляет элементы (например, при повторной визуализации шаблона). Это выглядит следующим образом:

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

Таким образом, в функции «INIT» вы бы зарегистрировать Dispose функцию обратного вызова для элемента, будучи связанным и вы бы иметь возможность работать независимо от очистки код, который вы хотели бы.

+0

Это определенно решит мою проблему. Жаль, что он не назывался unrender. Спасибо RP! –

+0

Если вы подключаетесь к другим библиотекам, которые выполняют свои собственные манипуляции с DOM (обычно в приложениях с одной страницей), вам может потребоваться рассмотреть подход jQuery, ниже которого запускаются триггеры для любого удаления DOM (а не только те, которые запускаются нокаутом). Полезно, если вы уже ссылаетесь на jQuery. –

3

Я считаю, что предоставленное здесь решение будет работать, только если Knockout - это тот, который удаляет узел DOM (т. Е. Когда он реджигирует шаблоны). Мне было трудно заставить его срабатывать при определенных условиях. Могут быть сценарии, в которых вам необходимо выполнить обратный вызов независимо от того, как ваш элемент был удален; будь то с нокаутом или через jQuery.html() и т. д. (особенно в одностраничном приложении).

Я приготовил другой подход для добавления такого крючка с небольшой помощью jQuery. Используя API специальных событий (которые хорошо описаны here), вы можете добавить метод, который запускается, когда конкретное событие removed с узла DOM (что-то происходит при срыве).

Если вы используете Нокаут в сочетании с 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 post.

+0

Я не уверен, как вы получили это ** var eventName = '_unique_unLoadEventName ____ 12345'; ** Просто пытаюсь понять, потому что я столкнулся с подобной ситуацией. – nimgrg

+0

Это просто строка, которую я вытащил из шляпы. Это может быть все, что вы хотите, я просто хотел убедиться, что он уникален и не сталкивался с другими плагинами или сторонним кодом, которые добавили бы свои собственные обработчики событий. В этом примере это немного преувеличено. –

+0

может просто изменить '_unique_unLoadEventName____12345' на 'your_unique_unLoad_event' –