1

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.

1
  • 2
    You need to push directly to the observable, not to the array it returns Commented Jul 14, 2017 at 8:33

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Wow... perfect! Thanks! That resolved it. I'm battling to understand when to use () and when not to. Maybe is a context issue I'm not understanding, but your fix has worked. Thank you.

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.