Reputation: 18734
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.
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
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