I have simple HTML markup with a list of my viewmodels in it and template. Also, I have my viewmodel in <pre>
section:
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="col-md-12">
<div class="panel panel-primary">
<div class="panel-heading">
Names
<button type="button" class="btn btn-link" data-bind="click: addName">
<span class="glyphicon glyphicon-plus"></span>
</button>
</div>
<div class="panel-body">
<ul class="list-group" id="namesList" data-bind="foreach: Names">
<li class="list-group-item"><my-comp></my-comp></li>
</ul>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="col-md-12">
<pre data-bind="text: ko.toJSON(Names, null, 2)"></pre>
</div>
</div>
</div>
</div>
<script type="text/html" id="fullNameTmpl">
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<p>First name: <input data-bind="textInput: firstName" /></p>
<p>Last name: <input data-bind="textInput: lastName" /></p>
<p>Full name: <input data-bind="textInput: fullName"></p>
<button data-bind="click: capitalizeLastName">Go caps</button>
</script>
<script>
function AppViewModel() {
var self = this;
self.firstName = ko.observable("Bert");
self.lastName = ko.observable("Bertington");
this.fullName = ko.pureComputed({
read: function () {
return self.firstName() + " " + self.lastName();
},
write: function (value) {
var lastSpacePos = value.lastIndexOf(" ");
if (lastSpacePos > 0) {
self.firstName(value.substring(0, lastSpacePos));
self.lastName(value.substring(lastSpacePos + 1));
}
},
owner: self
});
self.capitalizeLastName = function () {
var currentVal = this.lastName();
this.lastName(currentVal.toUpperCase());
};
}
ko.components.register('my-comp', {
viewModel: AppViewModel,
template: { element: "fullNameTmpl" }
});
function NamesViewModel() {
var self = this;
self.Names = ko.observableArray();
self.addName = function () {
var vm = ko.observable(new AppViewModel());
self.Names.push(vm);
}
}
ko.applyBindings(new NamesViewModel());
</script>
It works good, I can add an item to list and data binding in these items works. When I add new AppViewModel
, I can see it in <pre>
section, in Names
array. The problem is that when I'm changing some values in nested viewmodel, like typing new last name, whatever, there are no changes in <pre>
section in current viewmodel in Names
array.
How can I make a truly observable array of observables? What's the most profitable way to add components like this? I've already done nested viewmodel observable, but it seems doesn't work.
addName
method, I addko.observable
, doesn't this enough? – Yurii N.