I want to make all inner employee properties as observable so I've tried the knockout mapping plugin. However, after using it data is not getting bound properly. Here is the javascript code:
var employeeViewModel = new function () {
var self = this;
self.employees = ko.observableArray();
self.loading = ko.observable(true);
}();
$(document).ready(function () {
ko.applyBindings(employeeViewModel);
GetEmployees();
});
function GetEmployees()
{
$.get('/api/Employees', null, function (data) {
if (employeeViewModel.employees.length == 0) {
employeeViewModel.employees = ko.mapping.fromJS(data);
}
else {
ko.mapping.fromJS(data, employeeViewModel.employees);
}
//employeeViewModel.employees(data); //This works but want to make all inner properties as observable
employeeViewModel.loading(false);
});
}
HTML Code:
<div class="loadingImg" data-bind="visible: loading()"></div>
<table class="table table-bordered" data-bind="visible: !loading()">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Salary</th>
</tr>
</thead>
<tbody data-bind="foreach:employees">
<tr data-bind="template: {name: 'edit-template', data: $data }"></tr>
</tbody>
</table>
<script type="text/html" id="display-template">
<td data-bind="text: Name"></td>
<td data-bind="text: Email"></td>
<td data-bind="moneyFormat: Salary"></td>
</script>
<script type="text/html" id="edit-template">
<td><input class="form-control" type="text" data-bind="value: Name" /></td>
<td><input class="form-control" type="text" data-bind="value: Email" /></td>
<td><input class="form-control" type="text" data-bind="value: Salary" /></td>
</script>
The main issue is that it is appearing but not getting binded somehow. Here is the result: -
Below code works but how to achieve same via mapping plugin? I thought we can do same in 1 line by mapping plugin but it is not working.!! Need help.. May be I am missing something here..
employeeViewModel.employees(ko.utils.arrayMap(data, function (employee) {
var obsEmployee = {
Name: ko.observable(employee.Name),
Email: ko.observable(employee.Email),
Salary: ko.observable(employee.Salary)
}
return obsEmployee;
}
));
Don't create the
employees
observableArray. It's getting bound byapplyBindings
, then you re-assign it fromko.mapping.fromJS
. You'll need to use anif
binding instead ofvisible
to prevent knockout from trying to access employees before it has been mapped and bound.Example: http://jsfiddle.net/qxc19joy/