I have a feeling I'm missing something simple here, but just can't quite grok this. Here is my script:
function FormDefinition()
{
var self = this;
self.Fields = ko.observableArray([new FieldDefinition()]);
}
function FieldDefinition()
{
var self = this;
self.Name = "Test";
}
function ViewModel()
{
var self = this;
self.formDef = ko.observable(new FormDefinition());
self.Name = "bob"
self.addField = function(){
this.formDef().Fields().push(new FieldDefinition());
}
}
ko.applyBindings(new ViewModel());
and here is my markup:
<a data-bind="click: addField">Add</a><br/>
<span data-bind="text: Name"></span>
<ul data-bind="foreach: formDef().Fields">
<li data-bind="text: Name"></li>
</ul>
and here is a jsFiddle: http://jsfiddle.net/5xSmr/
Expected behavior is that clicking 'Add' would cause the ui to update. debugging reveals that addfield is getting called.
Activating Knockout But since the browser doesn't know what it means, you need to activate Knockout to make it take effect. To activate Knockout, add the following line to a <script> block: ko. applyBindings(myViewModel);
An observableArray just tracks which objects it holds, and notifies listeners when objects are added or removed.
Deferred – Notifications happen asynchronously, immediately after the current task and generally before any UI redraws. Rate-limited – Notifications happen after the specified period of time (a minimum of 2-10 ms depending on the browser).
ObservableArray is an array that allows listeners to track changes when they occur.
Fixed your fiddle: http://jsfiddle.net/5xSmr/2/
<a data-bind="click: AddField">Add</a><br/>
<span data-bind="text: Name"></span>
<ul data-bind="foreach: formDef().Fields()">
<li data-bind="text: Name"></li>
</ul>
function FormDefinition()
{
var self = this;
self.Fields = ko.observableArray();
}
function FieldDefinition()
{
var self = this;
self.Name = "Test";
}
function ViewModel()
{
var self = this;
self.formDef = ko.observable(new FormDefinition());
self.Name = "bob"
self.AddField = function(){
this.formDef().Fields.push({Name:"test"});
}
}
ko.applyBindings(new ViewModel());
The main problem was that you were calling Fields() and not just Fields. Fields() return the unwrapped array and by pushing directly to it, ko would never know about it.
Here you go :-)
http://jsfiddle.net/JasonMore/Q6J6a/3/
View
<a href='#' data-bind="click: AddField">Add</a><br/>
<span data-bind="text: Name"></span>
<ul data-bind="foreach: formDef.Fields">
<li data-bind="text: Name"></li>
</ul>
Javascript
var FormDefinition = function ()
{
var self = this;
self.Fields = ko.observableArray();
}
var ViewModel = function()
{
var self = this;
self.formDef = new FormDefinition();
self.Name = ko.observable("bob");
self.AddField = function(){
self.formDef.Fields.push({Name:"test"});
}
}
ko.applyBindings(new ViewModel());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With