Reputation: 11
I am new to knockout js. I have already completed few simple examples successfully and this time trying a little bit complex one using asp.net Web Api 2 as the back end service. I use following data structure at the back end.
public class Customer
{
public int CustomerID { get; set; }
public string CustomerName { get; set; }
public string NIC { get; set; }
public DateTime DateOfBirth { get; set; }
public decimal Salary { get; set; }
public int DepartmentID { get; set; }
public List<CustomerAddress> CustomerAddresses { get; set; }
}
public class CustomerAddress
{
public int CustomerAddressID { get; set; }
public int CustomerID { get; set; }
public int CustomerAddressTypeID { get; set; }
public string Address { get; set; }
}
public class CustomerAddressType
{
public int CustomerAddressTypeID { get; set; }
public string CustomerAddressTypeName { get; set; }
}
A customer can have multiple address and each and every address has CustomerAddressType. I want to get one customer object from the back end and edit particular customer in the following view. Addresses can be added and deleted in the bottom grid.
Customer Edit View
Javascript view model
$(document).ready(function () {
InitiCustomerViewModel();
GetCustomer();
});
function InitiCustomerViewModel() {
customerViewModel = new CustomerViewModel();
ko.applyBindings(customerViewModel);
customerViewModel.CustomerID(customerID);
}
function CustomerViewModel() {
this.CustomerID = ko.observable("");
this.CustomerName = ko.observable("");
this.NIC = ko.observable("");
this.DateOfBirth = ko.observable("");
this.Salary = ko.observable("");
this.DepartmentID = ko.observable("");
this.CustomerAddresses = ko.observableArray("");
this.DepartmentList = ko.observableArray("");
this.AddressTypeList = ko.observableArray("");
console.info(this.AddressTypeList());
}
function GetCustomer() {
GetDepartmentList();
GetAddressTypeList();
if (customerViewModel.CustomerID() > 0) {
var jqxhr = $.get("/api/CustomerApi/GetCustomer?customerID=" + customerViewModel.CustomerID(), null, function (res) {
LoadCustomerCompleted(res);
},
"json"
).fail(function (response) {
alert("Request Failed");
});
}
}
function GetDepartmentList() {
var jqxhr = $.get("/api/CustomerApi/GetDepartmentList", null, function (res) {
customerViewModel.DepartmentList.removeAll();
for (i = 0; i < res.length; i++) {
customerViewModel.DepartmentList.push(res[i]);
}
},
"json"
).fail(function (response) {
alert("Request Failed");
});
}
function GetAddressTypeList() {
var jqxhr = $.get("/api/CustomerApi/GetAddressTypeList", null, function (responce) {
customerViewModel.AddressTypeList.removeAll();
for (i = 0; i < responce.length; i++) {
customerViewModel.AddressTypeList.push(responce[i]);
}
},
"json"
).fail(function (response) {
alert("Request Failed");
});
}
function LoadCustomerCompleted(response) {
customerViewModel.CustomerID(response.CustomerID);
customerViewModel.CustomerName(response.CustomerName);
customerViewModel.NIC(response.NIC);
customerViewModel.Salary(response.Salary);
customerViewModel.DepartmentID(response.DepartmentID);
customerViewModel.DateOfBirth(response.DateOfBirth);
customerViewModel.CustomerAddresses.removeAll();
for (i = 0; i < response.CustomerAddresses.length; i++) {
customerViewModel.CustomerAddresses.push(response.CustomerAddresses[i]);
}
}
HTML View
@model KnockoutJSWithWebAPI.Models.Customer
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>CustomerMaintanance</h2>
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Customer</h4>
<hr />
<div class="form-group">
@Html.LabelFor(model => model.CustomerName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<input type="text" class="form-control" data-bind="value: CustomerName" />
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.NIC, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<input type="text" class="form-control" data-bind="value: NIC" />
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.DateOfBirth, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<input type="text" class="form-control" data-bind="value: DateOfBirth" />
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Salary, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<input type="text" class="form-control" data-bind="value: Salary" />
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.DepartmentID, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<select class="form-control" data-bind="options: DepartmentList, optionsText: 'DepartmentName', optionsValue:'DepartmentID', value: DepartmentID, optionsCaption: '--Select a Department--'"></select>
</div>
</div>
<div>
<table class="table table-striped">
<thead>
<tr>
<td>Adrress Type</td>
<td>Address</td>
</tr>
</thead>
<tbody data-bind="foreach: CustomerAddresses">
<tr>
<td>
<select class="form-control" data-bind="options: $root.AddressTypeList, optionsText: $root.AddressTypeList. CustomerAddressTypeName, value: $data.CustomerAddressTypeID, optionsCaption: '--Select Address Type--'"></select>
</td>
<td data-bind="text: Address"></td>
</tr>
</tbody>
</table>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Add Address" class="btn btn-default" />
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
<script type="text/javascript">
var customerID = "@Model.CustomerID";
</script>
<script type="text/javascript" src="@Url.Content("~/ViewModels/CustomerMaintanance.js")">
</script>
All the fields are binding correctly except the AddressType drop down in the grid. It shows [object,object] instead of CustomerAddressTypeName.
Address type Dropdown
Please help me to find out the issue in my application.
Upvotes: 1
Views: 157
Reputation: 4304
the "optionsText" binding on your dropdown takes a string for the name of the property that contains the display text. It should probably read "optionsText: 'CustomerAddressTypeName'" instead of "optionsText: $root.AddressTypeList. CustomerAddressTypeName"
Upvotes: 1