Matt
Matt

Reputation: 6953

KnockoutJS: ko.mapping.fromJS problems

My JS:

<script type="text/javascript">
        function DictionaryEntry() {
            var self = this;
            self.Simplified = ko.observable("");
            self.Traditional = ko.observable("");
            self.Phonetic = ko.observable("");
            self.Definition = ko.observable("");
        }

        function DictionaryModel() {
            var self = this;

            self.entries = ko.observableArray([]);
        }

        var viewModel = new DictionaryModel();
        viewModel.update = function () {
            var self = this;

            var f = $("#fSearch");
            $.ajax({
                url: f.attr('action'),
                type: f.attr('method'),
                data: f.serialize(),
                success: function (result) {
                    self.entries = ko.mapping.fromJS(result, viewModel);
                }
            });

            return false;
        }

        ko.applyBindings(viewModel);

    </script>

Table html:

<table class="table table-striped">
        <thead>
            <tr>
                <th>@T("Simplified")</th>
                <th>@T("Traditional")</th>
                <th>@T("Phonetic")</th>
                <th>@T("Definition")</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: entries">
            <tr>
                <td data-bind="text: Simplified"></td>
                <td data-bind="text: Traditional"></td>
                <td data-bind="text: Phonetic"></td>
                <td data-bind="text: Definition"></td>
            </tr>    
        </tbody>
    </table>

A button which triggers the update.. searches the dictionary and returns results to replace what is currently in the table:

<input type="submit" value="Search" class="btn" data-bind="click: update" />

in my action method, this is what is returned:

return Json(new
                {
                    // here list is a List<T> with the 4 properties to display in UI
                    entries = list,
                    IndexOfPage = indexOfPage,
                    SizeOfPage = sizeOfPage,
                    TotalRecords = totalRecords,
                    Pages = (int)Math.Ceiling((double)totalRecords / sizeOfPage)
                });

Problem I am having is that it seems to be stuck in an infinite loop for some reason. I put a breakpoint in the action and I can see it goes there over-and-over again... continuously..

What am I doing wrong? Completely new to knockout (and not exactly super at JS either, so please don't give a vague answer)

Upvotes: 3

Views: 8205

Answers (2)

Jason Goemaat
Jason Goemaat

Reputation: 29214

If result has an entries propery that is your list, you should just have to 'ko.mapping.fromJS(result, viewModel)'. Setting entries to the result gives you an entries property with it's own entries property.

Upvotes: 0

msarchet
msarchet

Reputation: 15242

There is a callback that is called update in knockout.

What's happening is when you call the mapping, it's triggering that callback ( which exists as a function on the viewModel ). This is causing your update function to be called, thus causing an infinite loop.

http://knockoutjs.com/documentation/plugins-mapping.html

look for the section about Customizing object updating using “update”

Upvotes: 3

Related Questions