1

I have a knockout template:

<script type="text/javascript" id="myList">        
  // template stuff here                   
</script>

I call it in with the foreach option:

<div data-bind="template: { name:'myList', foreach: ItemList }"></div>

I get the view model form my controller and use the following Javascript to bind it:

var viewModel = ko.mapping.fromJS(@Html.Raw(JsonConvert.SerializeObject(Model));                                        
ko.applyBindings(viewModel, document.getElementById("contentsDetails"));

I return a few items from my controller and everything renders fine.

My problem is that if I add to my observable array

var itemToAdd = {
            Name:  ko.observable("name a"),
            Desc:  ko.observable("desc a")
 }

 viewModel.MyObservableArray().push(itemToAdd);

I have checked the array is observable using:

 console.log(ko.isObservable(viewModel.MyObservableArray));

It does not update the UI template by adding the new item to the list.

What am I doing wrong here?

1 Answer 1

9

It's this line:

viewModel.MyObservableArray().push(itemToAdd);

By putting brackets after MyObservableArray, you're accessing the underlying array, and directly pushing the value into it. Knockout doesn't see this change. Instead, call .push directly on the observableArray:

viewModel.MyObservableArray.push(itemToAdd);

This is a method in knockout that will update the underlying array and notify any subscribers of the change, and will result in the UI being updated.

Alternatively, you can keep it as you have it, but inform knockout that it has changed, which will trigger the updates:

viewModel.MyObservableArray().push(itemToAdd);
viewModel.MyObservableArray.valueHasMutated();
Sign up to request clarification or add additional context in comments.

2 Comments

Just wanted to understand.... viewModel.MyObservableArray().push(itemToAdd); This pushes the value but it wil be no longer an observable kind of??
@G_S viewModel.MyObservableArray() returns the underlying native javascript array - the observableArray wrapper still exists around it. If you push a value into the underlying array directly, knockout doesn't know you've done so. The observableArray object redefines the array methods to both update the underlying native array, and provide notifications to anything depending on that observableArray. That's why you can call .valueHasMutated on the observableArray after changing the underlying array - it still exists and can then update itself properly based on the new contents.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.