2012-04-25 20 views
24

Tengo un manipulador de encuadernación que utiliza plupload para arrastrar y soltar y carga de ajax.¿Función de desmontaje del manipulador de encuadernación a tope?

Para usar la secuencia de comandos plupload creo una instancia de plupload que a su vez vincula los detectores de eventos a los elementos de DOM.

Eso funciona bien.

Sin embargo, tengo una lista de "carpetas" y cuando hago clic en una carpeta, aparece una lista de archivos en esa carpeta. Reutilizo los mismos elementos de DOM para esto vinculando documentos seleccionadosFolder() utilizando foreach.

El problema que tengo es que en mi controlador de encuadernación hago todas mis cosas en la función init y como reutilizo los elementos del DOM, obtienen múltiples manejadores de eventos ligados a ellos. Esto hace que los eventos de arrastrar y soltar se envíen a todos los controladores. Esto significa que si dejo caer un archivo en la lista de archivos representados, el evento de caída también se activará en todas las listas de archivos previamente procesadas.

Lo que estoy buscando es algún tipo de función de eliminación o limpieza en el controlador de enlace, por lo que puedo anular el registro de todos los eventos siempre que no se entregue una lista de archivos (¿es una palabra?).

Quizás no podamos detectar la desvinculación? ¿Cómo manejaría esto? Preferiría no tener una instancia global, ya que eso me impediría usar el enlace en múltiples lugares al mismo tiempo.

Lo sentimos, pero no le damos ningún código. Estoy en el cajero automático de mi teléfono celular.

¡Salud!

Respuesta

32

Puede registrar un controlador que se ejecutará siempre que KO elimine elementos (como cuando se vuelve a representar una plantilla). Parece que:

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

Por lo tanto, en su función "init" se registraría una devolución de llamada disponer para el elemento que se está atado y que tendrían la oportunidad de ejecutar cualquier código de limpieza que le gustaría.

+0

Eso definitivamente resolvería mi problema. Es una lástima que no se llamara "desintegración". Gracias RP! –

+0

Si se está mezclando con otras bibliotecas que hacen su propia manipulación DOM (común en aplicaciones de una sola página), entonces puede considerar el enfoque jQuery debajo que desencadena para cualquier eliminación DOM (no solo las desencadenadas por knockout). Útil si ya hace referencia a jQuery. –

3

Creo que la solución proporcionada aquí solo funcionará si Knockout es el que elimina el nodo DOM (es decir, cuando se rejigs plantillas). Me costó hacerlo disparar bajo ciertas condiciones. Puede haber situaciones en las que necesite que se ejecute una devolución de llamada independientemente de cómo se eliminó su elemento; ya sea con Knockout o vía jQuery.html(), etc. (especialmente en una aplicación de una sola página).

He elaborado un enfoque diferente para agregar un gancho con un poco de ayuda de jQuery. Usando la API de eventos especiales (que están bien descritos en here), puede agregar un método que se ejecuta cuando un evento en particular es removed desde un nodo DOM (algo que ocurre durante el desmontaje).

Si está utilizando Knockout en conjunción con jQuery, se puede envolver esto en una unión a ser algo como esto nocaut:

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); 
    } 
}; 

entonces usted puede utilizar esto en cualquier elemento de la siguiente manera:

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

Debo créditos a este SO post.

+0

No estoy seguro de cómo obtuvo esto ** var eventName = '_unique_unLoadEventName ____ 12345'; ** Estoy tratando de entender porque me encontré con una situación similar. – nimgrg

+0

Eso es solo una cadena que saqué de un sombrero. Puede ser lo que quieras, solo quería asegurarte de que fuera único y no colisionara con ningún otro complemento o código de terceros que agregara sus propios controladores de eventos. Es ligeramente exagerado en este ejemplo ... –

+0

quizás solo cambie '_unique_unLoadEventName____12345' por 'your_unique_unLoad_event' –

Cuestiones relacionadas