knockout.js - Knockout observable change not detected if value changed externally -
i have list of text boxes bound ko.observablearray.
i have make sure text box values can't blank, , jquery setting value 0 if it's blank on blur()
the problem value change done jquery not registered knockout.
how observe value change in model?
see simplified fiddle point across - http://jsfiddle.net/k45gd/1/
html
<input type="number" data-bind="value: age" /> <span data-bind="text: age"></span> <button data-bind="click: setageexternally">i want label change 0</button> js
var model = function() { this.age = ko.observable(21); //this code outside of model, oversimplification this.setageexternally = function(){ $('input').val(0); } }; ko.applybindings(new model());
in example provide, you're updating input box code:
this.setageexternally = function(){ $('input').val(0); } considering input bound age property, simpler this:
this.setageexternally = function(){ this.age(0); } however, isn't needed, age property exposed on viewmodel. external code this, , setageexternally method isn't needed:
model.age(0); let's jump original problem - 1 describe don't post code for. mention have list of input boxes bound observable array.
there interesting gotcha need aware of when working observable array:
from documentation @ http://knockoutjs.com/documentation/observablearrays.html:
key point: observablearray tracks objects in array, not state of objects
simply putting object observablearray doesn’t make of object’s properties observable. of course, can make properties observable if wish, that’s independent choice. observablearray tracks objects holds, , notifies listeners when objects added or removed.
given requirements list, there isn't need jquery @ all. can try three-part solution:
make observablearray contain observables. you'd end like:
var model = function() { this.ages = ko.observablearray([ {age: ko.observable(13)}, {age: ko.observable(18)}, {age: ko.observable(16)}, {age: ko.observable(13)} ]); };next, create knockout extender resets 0 automatically if blank
ko.extenders.defaultifblank = function(target, defaultvalue) { var result = ko.computed({ read: target, //always return original observables value write: function(newvalue) { if (newvalue == "") { target(defaultvalue); } else { target(newvalue); } } }); //initialize current value make sure not blank result(target()); //return new computed observable return result; };apply extender observables in array
var model = function() { this.ages = ko.observablearray([ ko.observable(13).extend({defaultifblank: "0"}), ko.observable(18).extend({defaultifblank: "0"}), ko.observable(16).extend({defaultifblank: "0"}), ko.observable(13).extend({defaultifblank: "0"}) ]); };
working fiddle: http://jsfiddle.net/tlarson/gf3xe/
Comments
Post a Comment