2015-04-20 21 views
7

Cercando di ottenere Knockout base click legame istituito, come nell'esempio qui sotto:Knockout click vincolante strano comportamento

<button id="btn-a" class="btn" data-bind="css: {'btn-primary':mode() == 'manual'}, click: $root.mode('manual')">Manual</button> 
<button id="btn-b" class="btn" data-bind="css: {'btn-primary':mode() == 'automatic'}, click: $root.mode('automatic')">Automatic</button> 

<label>MODE: </label><span data-bind="text:mode()"></span> 

<script> 

$(function() { 

    var TestModel = function() {   
     var self = this; 
     this.mode = ko.observable('manual'); 
    }; 

    var testModel = new TestModel(); 
    window.testModel = testModel; 
    ko.applyBindings(testModel); 

}); 

Fiddle: http://jsfiddle.net/aq85wk65/

Tuttavia, l'esecuzione in due aspetti:

  1. Il binding causa il valore mode() per l'avvio come "automatico", anche se inizializzarlo in modo esplicito su "manuale".
  2. Ogni volta che un pulsante viene premuto, la console JavaScript mostra:

Uncaught TypeError: h.apply is not a function

risposta

6

Il problema è che il tuo 012 Il gestoreè invocando la funzione anziché utilizzare il suo riferimento.

Ecco perché sei finito con modeauto, perché click: $root.mode('automatic') sta impostando il valore osservabile.

Prova a modificare:

click: $root.mode.bind($root, 'manual') 
3

Sia il .bind risposta o la risposta function() {} funzionerà; ma generalmente preferisco evitare di definire le funzioni nelle mie viste laddove possibile, e invece spostare quella logica su ViewModel.

Quindi un'altra opzione, e quella che probabilmente andrei in questo caso, è definire una funzione viewModel.setToManual() e una funzione viewModel.setToAutomatic().

Poi il gestore di legame sarebbe solo

click: setToAutomatic 

Non solo è che più pulita nella vista, ma protegge la vista contro la modifica della struttura del ViewModel così, fino a quando il comportamento dei setToAutomatic (e probabilmente un equivalente isAutomatic) sono conservati.

+0

normalmente sarei d'accordo con te completamente, ma in questo caso sta impostando il valore di un osservabile da un controllo. Se avesse diverse opzioni, definire un setter unico per ciascuno sarebbe un po 'troppo. – dfperry