NullReference
NullReference

Reputation: 4484

How to add a function to a mapped object?

I'm getting an array of object from the server that I'd like to add a method to. In the sample below I'd like it to be called doAlert. When I try to bind to the doAlert using data-bind="click: doAlert" knockout throws an exception. I suspect I'm adding the function wrong so any advice would be greatly appreciated. Thanks

   $(document).ready(function () {
    var url = GetUrl();
    $.getJSON(url, function (data) {

        var mapping = {   
            doAlert: function (options) {
                alert('test');    
            }
        }

        var viewModel = ko.mapping.fromJS(data, mapping);
        ko.applyBindings(viewModel);
    });
});


<ul data-bind="foreach: $data">
<li>
    <span data-bind="text: Title"></span>
    <div class="btn-group" style="display:inline">
        <a class="btn-small btn dropdown-toggle" data-toggle="dropdown" href="#">Action
                    <span class="caret"></span>
        </a>
        <ul class="dropdown-menu">
            <a data-bind="click: doAlert"><li>Edit</li></a>
            <a><li>Delete</li></a>
        </ul>
    </div>
</li>

Upvotes: 1

Views: 372

Answers (1)

Luffy
Luffy

Reputation: 2337

Checkout this JsFiddle Demo

I change your viewModel little bit for the demo but your html remains same.

You need to define a create function inside the mapping.

// Fake Data for demonstration
var fakeData = [{
    "id": 1,
    "Title": "C++"},
{
    "id": 2,
    "Title": "Java"},
{
    "id": 3,
    "Title": "JavaScript"},
{
    "id": 4,
    "Title": "Scala"},
{
    "id": 5,
    "Title": "Python"}
];


function Model() {

var self = this;

// You are using foreach syntax so we need to define an observableArray
this.dataArray = ko.observableArray([]);

this.loadData = function() {   
    $.ajax({
        type: 'POST',
        url: '/echo/json/',
        data: {
            json: ko.toJSON(fakeData)
        },
        success: function(data) {

            var mapping = {

                create: function(options) {                  
                    options.data.doAlert = function() {
                        alert(options.data.Title);
                    }
                    return options.data;
                }
            }
            // Map returning object into the our dataArray
            ko.mapping.fromJS(data, mapping, self.dataArray);
        },
        dataType: 'json'
    });
}
}
};

var viewModel = new Model();
ko.applyBindings(viewModel);
viewModel.loadData();​

Options parameter passing into the create function has some properties. We can reach our data with options.data property. Checkout for more information about options parameter at mapping documentation

Upvotes: 2

Related Questions