2012-04-25 11 views
24

Ho un gestore di binding a eliminazione diretta che utilizza il caricamento multiplo per il drag and drop e gli upload ajax.Funzione di smistamento del handler di binding Knockout?

Per utilizzare lo script di plupload, creo un'istanza di plupload che a sua volta associa i listener di eventi agli elementi DOM.

Ciò funziona correttamente.

Tuttavia, ho un elenco di "cartelle" e quando faccio clic su una cartella visualizzo un elenco di file in quella cartella. Riuso gli stessi elementi DOM per questo vincolando i documenti SelectedFolder(). Usando foreach.

Il problema che ho è che nel mio gestore di binding eseguo tutte le mie cose con i plupload nella funzione init e dal momento che riusino gli elementi DOM, ottengono più gestori di eventi associati a loro. Questo fa sì che gli eventi drag and drop vengano inviati ai gestori. Ciò significa che se si rilascia un file nell'elenco di file renderizzati, l'evento di rilascio si attiva anche su tutti gli elenchi di file precedentemente visualizzati.

Quello che sto cercando è una sorta di funzione di rimozione o cancellazione nel gestore di binding, in modo che io possa annullare la registrazione di tutti gli eventi ogni volta che un elenco di file non viene restituito (è una parola?).

Forse non è possibile rilevare l'annullamento? Come potrei quindi gestirlo? Preferirei non avere un'istanza globale, poiché ciò mi impedirebbe di utilizzare l'associazione su più siti contemporaneamente.

Mi dispiace per non aver fornito alcun codice. Sono al mio telefono cellulare.

Cheers!

risposta

32

È possibile registrare un gestore che verrà eseguito ogni volta che KO rimuove elementi (come quando un modello viene ricreato). Sembra che:

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

Così, nella funzione "init" si registrerebbe un callback dispose per l'elemento che viene legato e si dovrebbe avere l'opportunità di eseguire qualsiasi codice clean-up che si desidera.

+0

Questo risolverebbe sicuramente il mio problema. Peccato che non si chiamasse arroccato però. Grazie RP! –

+0

Se ci si sta mescolando con altre librerie che eseguono la propria manipolazione DOM (comune nelle applicazioni a pagina singola), si potrebbe prendere in considerazione l'approccio jQuery sotto il quale si innesca qualsiasi rimozione DOM (non solo quelle attivate da KO). Utile se si fa già riferimento a jQuery. –

3

Credo che la soluzione qui fornita funzionerà solo se Knockout è quello che rimuove il nodo DOM (cioè quando rifiuta i modelli). Ho avuto difficoltà a farlo innescare in determinate condizioni. Potrebbero esserci scenari in cui è necessario eseguire una richiamata indipendentemente da come il tuo elemento è stato rimosso; sia con Knockout, sia con jQuery.html(), ecc. (specialmente in un'applicazione a singola pagina).

Ho creato un approccio diverso per aggiungere un tale hook con un piccolo aiuto da jQuery. Utilizzando l'API degli eventi speciali (che sono ben descritti here), è possibile aggiungere un metodo che viene eseguito quando un particolare evento è removed da un nodo DOM (qualcosa che accade durante la rimozione).

Se si utilizza Knockout in collaborazione con jQuery, si può avvolgere questo in un ko vincolante per cercare qualcosa di simile:

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

è possibile utilizzare questo su qualsiasi elemento come questo:

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

Devo crediti a questo SO post.

+0

Non sono sicuro di come hai ottenuto questo ** var eventName = '_unique_unLoadEventName ____ 12345'; ** Sto solo cercando di capire perché mi sono imbattuto in una situazione simile. – nimgrg

+0

Questa è solo una stringa che ho tirato fuori da un cappello. Può essere tutto ciò che vuoi, volevo solo assicurarmi che fosse unico e non collidere con nessun altro plug-in o codice di terze parti che aggiungesse i propri gestori di eventi. È un po 'esagerato in questo esempio .. –

+0

forse cambia "_unique_unLoadEventName____12345" in "your_unique_unLoad_event" –

Problemi correlati