Struggling with implementing a viewModel within another viewModel in knockout. Any assistance would be greatly appreciated. Using typescript and aiming to have a list of address controls, each with their individual viewmodel.
Initially, the project functioned well with just one address control. However, upon adding the controls to a parent container viewmodel and utilizing components, the child viewmodel is consistently empty (i.e. {} as indicated by the alert statements below):
Refer to my app.ts file for complete code at https://github.com/richbeales/knockout-test
///<reference path="../node_modules/retyped-knockout-tsd-ambient/knockout.d.ts"/>
import * as ko from 'knockout';
import {AddressViewModel, Address} from './components/paf-widget';
ko.components.register('paf-address', {
viewModel: AddressViewModel, // { require: 'components/paf-widget' },
template: { require: 'text!components/paf-widget.html' }
});
class AddressesViewModel {
addressList: KnockoutObservableArray<AddressViewModel>;
constructor() {
this.addressList = ko.observableArray<AddressViewModel>();
}
addAddress = function () {
alert(ko.toJSON(this)); // returns {"addressList":[{}]}
var childVm = new AddressViewModel();
alert(ko.toJSON(childVm)); // returns {}
childVm.chosenAddress(new Address());
childVm.chosenAddress().Organisation = "Test";
alert(ko.toJSON(childVm)); // returns {}
var a = new Address();
a.AddressLine1 = "The Street";
alert(ko.toJSON(a)); // returns {"AddressLine1":"The Street"}
this.addressList.push(childVm);
}
}
var vm = new AddressesViewModel();
ko.applyBindings(vm);
here is my index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bootstrap with jQuery and KnockoutJS</title>
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<header>
</header>
<h1>App</h1>
Choose an Address
<pre data-bind="text: ko.toJSON(addressList, null, 2)"></pre>
<ul data-bind="foreach: {data: addressList, as: 'addrVm'}" style="list-style: none;">
<li class="addressli">
<pre data-bind="text: ko.toJSON(addrVm, null, 2)"></pre>
<div data-bind="component: {name: 'paf-address', with: addrVm }"></div>
</li>
</ul>
<button class="btn btn-primary" data-bind="click: addAddress">Add an address</button>
<footer>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.1/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.2/require.min.js" data-main="js/app"></script>
<script src="require-config.js"></script>
</body>
</html>