2012-11-03 15 views
6

Sto usando knockout.js. Sono bloccato in una situazione un po 'strana (è difficile da spiegare ma ci sto provando, scusa se non sono chiaro). Sto usando personalizzato vincolante e opzioni di rilegatura su un unico SelectList:Come ordinare gli attacchi a strappo?

<select data-bind="options : arrayOfOptions, optionsText: 'Name', 
      optionsValue: 'Name', chosen: { }"> 
    </select> 

ko.bindingHandlers.chosen = { 
    init: function (element, valueAccessor, allBindingAccessor, 
        viewModel, bindigContext) { 
     var options = ko.utils.unwrapObservable(valueAccessor() || {}); 
     $(element).chosen(options); 
    } 
}; 

Qui a SelectList runtime riempirò con tutte le opzioni disponibili dalla arrayOfOptions array e chosen è vincolante una consuetudine in cui Mi candido un CHOSEN PLUGIN su la select-list.

Ora il problema che sto affrontando qui è che nel collegamento personalizzato quando ho applicato il plug-in Scegli selezionate nell'elenco in quel momento l'elenco di selezione non è pieno con le opzioni dall'array . Significa in un termine semplice che custom binding è in esecuzione prima di options binding. Qualcuno può darmi una soluzione per questo in modo che l'associazione personalizzata venga applicata dopo l'associazione delle opzioni?

risposta

4

Spostare la chiamata su chosen nell'aggiornamento.

http://jsfiddle.net/jearles/avSfa/28/

-

ko.bindingHandlers.chosen = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) { 
     var allBindings = allBindingsAccessor(); 

     var options = {default: 'Select one...'}; 
     $.extend(options, allBindings.chosen) 

     $(element).attr('data-placeholder', options.default);     
    }, 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel) { 
     $(element).chosen(); 
    } 
}; 

-

In alternativa, è possibile utilizzare setTimeout per spostare la chiamata alla chosen alla parte inferiore della coda di esecuzione. Ciò consentirà alle opzioni Knockout di impegnare il tempo per eseguire il proprio lavoro prima che lo chosen provi a trasformarlo.

ko.bindingHandlers.chosen = { 
    init: function (element, valueAccessor, allBindingAccessor, 
        viewModel, bindingContext) { 
     var options = ko.utils.unwrapObservable(valueAccessor() || {}); 
     setTimeout(function() { $(element).chosen(options); }, 0); 
    } 
}; 
+0

Nel secondo esempio, le opzioni verranno impostate su un oggetto vuoto prima setTimeout è chiamato (e rimarranno vuoti). Deve essere assegnato quando viene attivato il setTimeout. –

1
ko.bindingHandlers.chosen = { 
init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
    var options = allBindingsAccessor().options; 

    options.subscribe(function (newValue) { 
     $(element).chosen(); 
     $(element).trigger("chosen:updated"); 
    }); 

    var value = allBindingsAccessor().value; 
    value.subscribe(function (newValue) { 
     $(element).trigger("chosen:updated"); 
    }); 
}, 
update: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
    if (element.options.length > 0) { 
     $(element).chosen(); 
     $(element).trigger("chosen:updated"); 
    } 
} 

};

questo ha funzionato per me con KO JS 3.0

+0

+1, questo mi ha portato alla soluzione per un problema simile, buon modello quando si desidera che l'associazione personalizzata esegua qualcosa dopo qualche altro binding (ma se si desidera eseguirlo una sola volta, è possibile anche distruggere l'utente). –

0

Mentre le risposte sopra possono risolvere il problema che è stato presentato, sembrano cadere a corto di personalizzazione del calo scelto menù a tendina, come ad esempio la disattivazione di ricerca passando { 'disable_search ':vero}.

Suggerisco le seguenti modifiche per consentire il passaggio della personalizzazione scelta nell'associazione.

<select data-bind="options : arrayOfOptions, optionsText: 'Name', 
    optionsValue: 'Name', chosen: { 'disable_search': true }"> 
</select> 

ko.bindingHandlers.chosen = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     var options = allBindingsAccessor().options; 
     var chosenOptions = allBindingsAccessor().chosen; 

     options.subscribe(function (newValue) { 
      $(element).chosen(chosenOptions); 
      $(element).trigger("chosen:updated"); 
     }); 

     var value = allBindingsAccessor().value; 
     value.subscribe(function (newValue) { 
      $(element).trigger("chosen:updated"); 
     }); 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     if (element.options.length > 0) { 
      var chosenOptions = allBindingsAccessor().chosen; 
      $(element).chosen(chosenOptions); 
      $(element).trigger("chosen:updated"); 
     } 
    } 
}; 
8

Creare una proprietà after con una matrice di nomi bindingHandler da cui dipende questa associazione.

ko.bindingHandlers.chosen = { init: function (element, valueAccessor, allBindingAccessor, viewModel, bindigContext) { var options = ko.utils.unwrapObservable(valueAccessor() || {}); $(element).chosen(options); }, after:['options'] };

+0

@ user1740381 non soddisfa esattamente ciò che stai cercando? – DrSammyD

+0

In realtà pensavo che avrebbe funzionato, ma non riesco a farlo funzionare. dopo: ['options'] non sembra funzionare ... cosa c'è nell'array after? Inoltre non è menzionato nella documentazione per quanto posso vedere ... –

+2

Ecco un [jsfiddle] (http://jsfiddle.net/2uaLxdrk/). '['options']' è una lista di nomi bindingHandler, e controllerà se l 'attuale data-bind contiene uno di questi e rimanderà fino a dopo che quelli sono stati rilegati.E tu hai ragione, non è nei documenti, l'ho trovato nel codice sorgente. – DrSammyD

Problemi correlati