Craig
Craig

Reputation: 18734

Add object to ObservableArray

I have an data object which is dynamic as it was read from a WebApi Load Data call... and then converted into an observable using:

 $.get("/api/PlateTemplate/Get", { id: self.TemplateId() }).done(function (data) {
            ko.mapping.fromJS(data, {}, self.Data);  
            self.IsDataLoaded(true);
        });

One of the fields is an observable array of another object type. I use this to render some tabs on my UI.

<div id="plateTemplate" data-bind="with: Data">
<ul class="nav nav-tabs" data-bind="foreach: PlateTemplateGroups">
                <li data-bind="css: {active: $index()==0}"><a data-toggle="tab" data-bind="attr: {href: ('#tabId' + $index())}"><span data-bind="text: Description"></span></a></li>
</ul>

This works. All good. I have a button which I would like to use to add a new tabl. I allow the user to type in a name, and then click the button. I want to add a new tab. So, I attempt to add a new item to my Data object:

But first, to check that my tab group is 'observed', I just hardcode a name change to the first tab:

self.Data().PlateTemplateGroups()[0].Description("hahahaha");

And as that executes, the first tabs display name changes. Also, when I post my self.Data() back to my controller, the changes are reflected.

Then I try to add a new item:

self.Data().PlateTemplateGroups().push({ Id: ko.observable(0), Description: ko.observable(name), Components: ko.observableArray([]) });

This executes, but no new tab appears.

However, when I post my model back to my .Net controller, I see the new item.

enter image description here

Is there any reason why the new tab never appears? Maybe I am adding to the obervableArray incorrectly? I'm worried why I need to reference the objects using () all the time as well.

Upvotes: 1

Views: 860

Answers (1)

Jose Luis
Jose Luis

Reputation: 994

In your ViewModel you have an observable property Data. This property has other properties, like an observable array called PlateTemplateGroups.

Because Data is an observable that contains an object, you need to call it as a function to get this object:

Data()

Now, you can add an element to PlateTemplateGroups with push():

 self.Data().PlateTemplateGroups.push( ... )

Here is a Codepen as example. You can click the button and a TemplateGroup is added.

Upvotes: 2

Related Questions