2
votes

I'm using the following markup (abridged) to display a list of person objects in a table. I would like to open an Edit Details popup when a row is clicked, but my rudimentary event binding isn't working for rows added to the table by Knockout data binding.

<script>
    function PersonModel(data) {
        var self = this;
        self.id = data.Id;
        self.firstName = data.FirstName;
    }
    $(function () {
        function personListModel() {
            var self = this;
            self.persons = ko.observableArray([]);
            $.getJSON("Person/IndexJson", function (allData) {
                var mappedPersons = $.map(allData, function (item) { return new PersonModel(item); });
                self.persons(mappedPersons);
            });
        }
        ko.applyBindings(new personListModel());
        $(".person-row").click(function () {
            alert("Hello ");
        });
    });
</script>
<table>
    <tbody data-bind="foreach: persons">
        <tr class="person-row" data-bind="attr: { 'data-id': id }">
            <td data-bind="text: firstName"></td>
            <td data-bind="text: surname"></td>
            <td data-bind="text: email"></td>
            <td data-bind="text: cell"></td>
        </tr>
    </tbody>
</table>

If I bind a click event handler from the JS console after the page has rendered and bound, that handler is correctly called, but the initial event binding in the code above simply doesn't work. What must I do to bind to rows generated by knockout. I thought it would simply be enough to bind the event handler after ko.applyBindings().

1

1 Answers

3
votes

You need to use the JQuery's on method to subscribe on events on DOM elements which are added after the page load:

$(".person-row").on("click", function(event){
    alert("Hello ");
});

Or you can use the click binding structure and handle the subscription with knockout:

function personListModel() {
    var self = this;
            ...

    self.personClicked = function(data) {
        alert("Hello ");
    }
}

And in your view:

<tr class="person-row" data-bind="attr: { 'data-id': id }, click: $root.personClicked">

You can see it in action in this fiddle.