Ravi Ram
Ravi Ram

Reputation: 24488

Custom view data-bind in KnockOutJS

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

Answers (2)

RP Niemeyer
RP Niemeyer

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

Jinesh Jain
Jinesh Jain

Reputation: 1242

// use () with item.Name and item.Abbreviation as below

this.NameAbbreviation = function (item) {
        return item.Name() + " " + item.Abbreviation();
    };

Upvotes: 0

Related Questions