javascript - observablearray - knockout visible
Knockout click binding comportamiento extraño (3)
Intentando configurar el enlace de Knockout básico, como se muestra en el siguiente ejemplo:
<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/
Sin embargo, se encuentra con dos problemas:
- La vinculación hace que el valor de
mode()
comience como ''automático'', aunque lo inicialicemos explícitamente como ''manual''. - Cada vez que se hace clic en un botón, la consola de JavaScript muestra:
Unkeught TypeError: h.apply no es una función
Debe ajustar sus manejadores de clics en la función:
http://jsfiddle.net/aq85wk65/1/
<button id="btn-a" class="btn" data-bind="css: {''btn-primary'':mode() == ''manual''}, click: function(){$root.mode(''manual'')}">Manual</button>
El problema es que su manejador de click
está invocando la función en lugar de usar su referencia.
Es por eso que click: $root.mode(''automatic'')
siendo el mode
auto
, porque click: $root.mode(''automatic'')
está configurando el valor observable.
Pruebe esto en su lugar:
click: $root.mode.bind($root, ''manual'')
O bien la respuesta .bind
o la respuesta function() {}
funcionará; pero, en general, prefiero evitar definir funciones en mis vistas siempre que sea posible y, en su lugar, mover esa lógica al ViewModel.
Otra opción, y la que probablemente viewModel.setToManual()
en este caso, es definir una función viewModel.setToManual()
y una función viewModel.setToAutomatic()
.
Entonces el controlador de enlace sería solo
click: setToAutomatic
No solo es más limpio en la vista, sino que también protege la vista frente a los cambios en la estructura de ViewModel, siempre que se setToAutomatic
el comportamiento de setToAutomatic
(y probablemente un isAutomatic
comparable).