How can I bind a ko.observableArray of strings?

slipheed picture slipheed · Apr 1, 2013 · Viewed 8.6k times · Source

I'm trying to bind a ko.observableArray of strings to a template, but I'm unable to get the template to pick up changes in the strings inside the array.

If I bind a set of objects instead of a set of strings, I get updates to the JSON, but they don't trigger anything until I actually change the first, non-array value. I'd prefer to find an array of strings, however, as I will be able to post the data model directly back to the server without any post-processing.

How can I get the updates to my arrays of strings to trigger, and how can I ensure that they correctly trigger changes without having to update a non-array value?

If it's not possible to bind to an observable array of strings, how I can get the events to trigger when updating the objects inside of the observable array?

See the example here: http://jsfiddle.net/gcEHC/2/

In this example, array3's data will be reflected in the model when value is changed, but changes to array1 and array2's data will never show up.

JS:

var ViewModel = function() {
    this.value = ko.observable("hi")
    this.array1 = ko.observableArray(["hi", "there"]);
    this.array2 = ko.observableArray([ko.observable("hi"), ko.observable("there")]);
    this.array3 = ko.observableArray([{ data: "hi" }, { data: "there" }]);
};

ko.applyBindings(new ViewModel());

HTML:

<div class='liveExample'>   
    <p><input data-bind='value: value' /></p> 
    <div data-bind="foreach: array1">
        <p><input data-bind='value: $data' /></p> 
    </div>
    <div data-bind="foreach: array2">
        <p><input data-bind='value: $data' /></p> 
    </div>
    <div data-bind="foreach: array3">
        <p><input data-bind='value: data' /></p> 
    </div>
</div>

<pre data-bind="text: ko.toJSON($data)"></pre>

Answer

user3846373 picture user3846373 · Jul 16, 2014

In KO 3, if you point to $rawData in the binding, the array2 example works as expected.