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 by applyBindings
, then you re-assign it from ko.mapping.fromJS
. You'll need to use an if
binding instead of visible
to prevent knockout from trying to access employees before it has been mapped and bound.
<table class="table table-bordered" data-bind="if: !loading()">
Example: http://jsfiddle.net/qxc19joy/