2013-02-14 15 views
18

ho un po 'di javascript:KnockoutJS valore di commutazione nei dati-bind

function ViewModel() { 
    var self = this; 
    self.highlight = ko.observable(true); 
} 

ko.applyBindings(new ViewModel()); 

E il codice html che lo integra:

<div data-bind="css: { highlighted: highlight }, click: highlight(!highlight())"> 
    random string 
</div> 

Quello che sto cercando di realizzare:

  1. La classe css 'evidenziata' per essere attivata solo quando l'evidenziazione var è vera
  2. Facendo clic su il div alternerà il valore bool di var clou
  3. risultato voluto: cliccando sul div per attivare/disattivare la sua classe CSS

Quello che sto ricevendo:

  1. Il valore iniziale di punto culminante è true, eppure la classe css inizia disattivata (se cambio il valore iniziale in false, la classe css è attivata: sembra che in qualche modo abbia attivato il click binding quando non ho ancora cliccato nulla)
  2. Il la classe css di div non si attiva fare clic su

Preferisco non creare una nuova funzione di clic corrispondente all'interno di ViewModel. Sto cercando, se possibile, un po 'di codice che posso inserire solo inline all'interno del data-bind.

Ecco il codice a JSFiddle: http://jsfiddle.net/4wt4x/1/

Qualcuno può spiegare cosa sta succedendo e quello che sto facendo in modo errato?

risposta

19

Il tuo click: highlight(!highlight()) non è corretto. Fare clic sta per provare a eseguire una funzione e quando l'associazione è stata inizializzata, l'evidenziazione avrebbe restituito qualunque fosse il suo valore ed è ciò che il clic sta tentando di eseguire (true o false nel tuo caso). Hai bisogno di fare qualcosa di simile:

Nel vostro javascript, posto nel modello:

self.toggleHighlight = function() { self.highlight(!self.highlight()) }; 

quindi modificare il legame di dire click: toggleHighlight

Come così: http://jsfiddle.net/KDypD/1/

potrebbe essere necessario per regolare il valore iniziale dell'evidenziazione e riflettere come desideri che la pagina venga visualizzata inizialmente.

+0

Grazie per la risposta. Non c'è modo di farlo da solo all'interno della stessa data-bind? Questo è quello che sto cercando, se possibile. – dk123

+1

Personalmente considererei una cattiva pratica mettere qualcosa di simile in una rilegatura. Il punto è mantenere la tua vista separata dal tuo javascript. Tuttavia, se lo vuoi davvero, puoi semplicemente fare clic su: function (self) {self.highlight (! Self.highlight())} per il bind, ma non lo consiglierei dal momento che il debug in un secondo momento sarebbe terminato dover trovare javascript in due posti invece di uno solo. Diventa un problema con progetti più grandi con più contributori. –

+0

Grazie per la risposta e il commento in più sulla struttura della vista. Vado con la tua idea e creo la funzione all'interno del javascript. Grazie! – dk123

38

So che è una vecchia domanda, ma forse potrebbe aiutare qualcuno. Se è necessario utilizzare ginocchiera in un sacco di posti, magari un po 'di zucchero personalizzato vincolante potrebbe aiutare:

Binding:

ko.bindingHandlers.toggleClick = { 
    init: function (element, valueAccessor) { 
     var value = valueAccessor(); 

     ko.utils.registerEventHandler(element, "click", function() { 
      value(!value()); 
     }); 
    } 
}; 

Usage:

<div data-bind="css: { highlighted: highlight }, toggleClick: highlight"> 
    random string 
</div> 

Esempio :

http://jsfiddle.net/A28UD/1/

Questo approccio mantiene alcune delle mie opinioni molto più pulite. Spero che sia d'aiuto.

+2

Questa dovrebbe essere la risposta accettata IMO. – MattSizzle

+1

ko.utils.registerEventHandler +1 – Moon

+0

Era esattamente quello che stavo cercando – Koscik

4

Se si vuole veramente farlo in linea:

<div data-bind="click: highlight.bind($root, !highlight()), css: { highlighted: highlight } "> 
    random string 
</div> 

cui punto forte è il osservabile booleano.

6

Un'altra opzione è quella di utilizzare un'estensione funzione riutilizzabile personalizzato (funzione personalizzata viene usato al posto di extender perché non ci sono parametri e sembra più pulito):

ko.observable.fn.toggleable = function() { 
    var self = this; 
    self.toggle = function() { 
     self(!self()); 
    }; 

    return self; 
}; 

Uso

self.highlight = ko.observable(true).toggleable(); 

Html

<div data-bind="css: { highlighted: highlight }, click: highlight.toggle"> 
    random string 
</div> 
+0

Preferisco questo metodo perché è quindi possibile utilizzare la funzionalità 'toggle' in qualsiasi tipo di evento, o anche nel codice. – Grinn