Search code examples
javascripthtmlrestknockout.jsknockout-mapping-plugin

How to bind multiple links with same knockout function passing different IDs


Question: I am new to KnockoutJS. Following example code is working for me. But you can see that fetch function is hard coded and working for only user with id=100. How can I create a Get link with each row in the html table list and pass id of that record to fetch function that shows record only for that particular row in console. Any Idea?

HTML:

<div  id="users-view-data">

    <button type="button" data-bind="click: fetch">Get</button>
    <button type="button" data-bind="click: remove">Delete</button>
    <button type="button" data-bind="click: listAll">Get All</button>

    <table>

        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Code</th>
            <th>Created</th>
            <th>Action</th>
        </tr>

        <tbody data-bind="foreach: collection">
            <tr>
                <td><span data-bind="text: id"></span></td>
                <td><span data-bind="text: name"></span></td>
                <td><span data-bind="text: code"></span></td>
                <td><span data-bind="text: created"></span></td>
                <td>Get Link will come here to call fetch funtion</td>
            </tr>
        </tbody>

    </table>
</div>

JS:

<script type="text/javascript">

(function() {

    'use strict';

    var UserViewModel = function() {
        this.service = ko.rest.service('http://domain/users');
        this.model = ko.observable( { id:0, name:'', code:'' } );
        this.collection = ko.observableArray([]);
    };

    UserViewModel.prototype.listAll = function() {
        var self = this;
        self.service.query(function(data) {
           self.collection(data);
        });
    };

    UserViewModel.prototype.fetch = function() {
        var self = this;
        self.service.load(100, function(data) {
            self.model(data);
            console.log(data);
        });
    };

    UserViewModel.prototype.remove = function() {
        var self = this;
        var code = ko.rest.get(self.model(), 'id');
        self.service.delete(code, function(data) {
            console.log(data);
        });
    };

    ko.applyBindings( new UserViewModel(), document.getElementById("users-view-data") );

})();

</script>

I am using following libraries:

  • knockout-3.3.0.js
  • knockout.mapping-latest.js
  • knockout-rest.min.js

Solution

  • Add a click handler to each row:

    <tr data-bind="click:function(){$root.fetch(id)}">
        <td><span data-bind="text: id"></span></td>
        <td><span data-bind="text: name"></span></td>
    </tr>
    

    modify your fetch function to take an id:

    UserViewModel.prototype.fetch = function(id) {
        var self = this;
        //do whatever with id
    };
    

    (simplified) fiddle