2012-12-24 15 views
5

Sto creando un binding Knockout che funzionerà come un wrapper attorno a un widget jQuery. Questo widget applica i gestori di eventi agli elementi figlio. Sfortunatamente, la gestione degli eventi del widget viene applicata direttamente agli elementi figlio, non delegati. Il problema è che ho un bind di foreach sullo stesso elemento, ma ho bisogno del bind personalizzato da applicare dopo il il bind di foreach viene applicato.Modifica dell'ordine in cui vengono applicati i binding Knockout

Ovviamente, la cosa giusta è riparare il plugin jQuery, ma questa non è un'opzione al momento. Mi chiedo se ci sono delle buone soluzioni alternative per me. C'è modo, per esempio, di fare una delle seguenti cose?

  1. rilevare se un particolare legame è stato applicato
  2. influenzano l'ordine di applicazione
  3. vincolante sicura forzare un altro legame avvenire

Aggiornamento:

Un aspetto I dovrebbe menzionare che questa associazione personalizzata e il legame foreach risiedono in un modello. Pertanto, le soluzioni che modificano direttamente il DOM non funzioneranno per me poiché modificheranno effettivamente il modello.

risposta

2

Se l'associazione dipende dal bind di foreach, perché non chiamarla dal bind personalizzato? Quindi non è nemmeno necessario fornirlo nell'attributo data-bind. Ho aiutato un altro utente Così l'altro giorno, verificare come io chiamo le opzioni di rilegatura dall'interno personalizzato vincolanti

http://jsfiddle.net/w9bsc/42/

ko.applyBindingsToNode(element, { options: valueAccessor(), optionsCaption: caption, optionsText: optionsText }, viewModel); 
+0

Grazie per la risposta. Ho effettivamente provato quello che hai fatto (usando 'applyBindingsToNode'), e sembra funzionare. Una complicazione che non ho menzionato prima è che il mio binding personalizzato è applicato a un template 'text/html'. Dopo aver eseguito 'applyBindingsToNode' con un' foreach', i nodi figli sono stati creati, ma sono stati inseriti in modo permanente nel DOM del modello, non nel DOM dell'istanza del modello, se sai cosa intendo. – Jacob

+0

Dovresti usare un modello di associazione che non è un foreach, ma forse questo è quello che hai fatto? – Anders

+0

Ho provato entrambi. In entrambi i casi, 'applyBindingsToNode' ha modificato il DOM all'interno del modello. – Jacob

2

Ho trovato una soluzione alternativa, ma è più di un trucco di quanto mi piace. Aspetterò comunque risposte migliori.

Quello che ho fatto è stato semplicemente questo:

ko.bindingHandlers.myHandler = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     if (allBindingsAccessor().foreach) { 
      setTimeout(doInit, 1); 
     } else { 
      doInit(); 
     } 

     function doInit() { 
      bindingContext.initializedMyHandler = true; 
      // Actual code 
     } 
    }, 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     if (bindingContext.initializedMyHandler) { 
      doUpdate(); 
     } else { 
      setTimeout(doUpdate, 1); 
     } 
     function doUpdate() { 
      // Actual code 
     } 
    } 
}; 

Fondamentalmente ho solo rimandare l'esecuzione con un timeout. In questo modo, il resto dei gestori di binding verrà eseguito per primo.

7

Aggiungi un dopo proprietà sulla vostra bindingHandler con una serie di dipendenze

ko.bindingHandlers.myHandler = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     // Actual code 
    }, 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     // Actual code 
    }, 
    after:['foreach'] 
}; 
+0

Questo non sembra funzionare - hai un link ad alcuni documenti o un violino che lo mostra in azione? –

+1

[sì, io] (http://jsfiddle.net/2uaLxdrk/8/) – DrSammyD

+0

Interessante - grazie. Abbastanza sicuro è nel codice knockout. Non sono sicuro del motivo per cui non ha funzionato quando l'ho provato. –

Problemi correlati