Reputation: 24488
I am having problems creating a custom field within KnockOutJS ViewModel.
HTML
<table class="table table-striped">
<thead><tr>
<th>name</th><th>abb</th><th>combo</th>
</tr></thead>
<tbody data-bind="foreach: clients"><tr>
<td data-bind="text: Name"></td>
<td data-bind="text: Abbreviation"></td>
<td data-bind="text: NameAbbreviation"></td>
</tr></tbody>
</table>
JS CODE
function ClientModel() {
var self = this;
// Bind all data to UI < -- working
self.clients = ko.observableArray(data);
// Not working
self.NameAbbreviation = ko.computed(function () {
return self.Name + " " + self.Abbreviation;
})
};
ko.applyBindings(new ClientModel());
JOSN DATA (working)
{"ID":14,"GUID":"c999b888-9566-2e50-a23c-07913d389f99","Name":"Aaron46","Abbreviation":"Corporate Customer","Website":"www.ts2mkg3d0oomo.com","Email":"[email protected]","Active":true,"ModifyDate":"1959-02-14T15:47:53.43","CreatedDate":"1987-09-26T00:37:13.52","CreatedDateString":"9/26/1987","ModifyDateString":"2/14/1959","Status":0,"Message":null},{"ID":443,"GUID":"12c60aa5-03f1-509c-5d49-9caf696c44ce","Name":"Abigail","Abbreviation":"Technical","Website":"www.wsfj97qccj1.com","Email":"[email protected]","Active":true,"ModifyDate":"2007-02-01T06:01:11.3","CreatedDate":"1963-05-11T01:23:21.11","CreatedDateString":"5/11/1963","ModifyDateString":"2/1/2007","Status":0,"Message":null},{"ID":136,"GUID":"63c65e85-0f9b-1f7c-328a-ca253a4881d1","Name":"Adrienne","Abbreviation":"Accounting","Website":"www.ixug6k4eqkjmnr.com","Email":"[email protected]","Active":false,"ModifyDate":"2000-12-14T08:11:31.83","CreatedDate":"1980-05-03T03:25:02.34","CreatedDateString":"5/3/1980","ModifyDateString":"12/14/2000","Status":0,"Message":null}
I am able to bind all the data with no issues, when I do not create a custom view field!
When I try to create NameAbbreviation custom field, I get an error
Error: Unable to parse bindings.
Message: ReferenceError: NameAbbreviation is not defined;
Bindings value: text: NameAbbreviation
I understand the error, as KO cannot find NameAbbreviation in the view.
How do I get this custom view NameAbbreviation to be used/seen by KO?
Upvotes: 0
Views: 386
Reputation: 114792
When you are in the foreach
loop, the scope is the array item that you are looping on. Your view model has NameAbbreviation
defined at the root level rather than on each item.
There are several approaches that you could take here.
The simplest is to just create a simple function on your view model that returns the formatted string and bind against it using $root
or $parent
.
function ClientModel() {
this.clients = ko.observableArray(data);
this.NameAbbreviation = function (item) {
return item.Name + " " + item.Abbreviation;
};
};
Then, in your UI bind like:
<tbody data-bind="foreach: clients">
<tr>
<td data-bind="text: Name"></td>
<td data-bind="text: Abbreviation"></td>
<td data-bind="text: $root.NameAbbreviation($data)"></td>
</tr>
</tbody>
Otherwise, you could consider creating a "item" constructor function that adds the NameAbbreviation
and then sending each raw data item through the constructor.
Another option would be to use the mapping plugin.
Upvotes: 3
Reputation: 1242
// use () with item.Name and item.Abbreviation as below
this.NameAbbreviation = function (item) {
return item.Name() + " " + item.Abbreviation();
};
Upvotes: 0