0

Example jsFiddle


I have a model that is a Calendar at the root level. This Calendar contains many days, each Day contains an Event, each Event contains attendees and each Attendee has 0 or more Intolerances.

So it looks like this:

function Calendar(data) {
    this.days = ko.observableArray(data.days);
}

function Day(data) {
    this.date = ko.observable(data.date);
    this.event = ko.observable(data.event);
    this.daysToEvent = ko.computed(function () {
        var diff = Math.abs(new Date(), this.date());
        return (((diff / 1000) / 60) / 60) / 24;
    }, this);
}

function Event(data) {
    this.name = ko.observable(data.name);
    this.attendees = ko.observableArray(data.attendees);
}

function Attendee(data) {
    this.name = ko.observable(data.name);
    this.age = ko.observable(data.age);
    this.intolerances = ko.observable(data.intolerances);
}

function Intolerance() {
    this.id = ko.observable(data.id);
}

I'm passing a JSON string to this model and using the ko.mapping plugin (just started using it) to wire it all up. What I'm not understanding though is how can I tell the plugin to use my objects during mapping?

I'm aware of the mapping options param, but at the moment I'm a newbie so not really "getting it" so to speak. I've attempted with this:

var viewModel = {
    calendar: null,
    loadCalendar: function () {
        ko.mapping.fromJSON(json, {
            create: function (opts) {
                return new Calendar({ days: opts.data.calendar })
            }
        }, viewModel.calendar);
    }
};

Which gets my my Calendar object and the days, but how (and what is the most correct way) do I further map my classes down the tree?

1 Answer 1

1

You can put the mapping code inside the ViewModels themself:

function Calendar(data) {
    this.days = ko.observableArray();

    // update the current ViewModel with the given data
    if (data) {
        ko.mapping.fromJS(data, {
            days: {
                // tell the mapping plugin how to create the days
                create: function(options) {
                    return new Day(options.data);
                }
            }
        }, this);
    }
}

function Day(data) {
    this.date = ko.observable();
    this.event = ko.observable();

    if (data) {
        ko.mapping.fromJS(data, {
            event: {
                create: function(options) {
                    return new Event(options.data);
                }
            }
        }, this);
    }

    this.daysToEvent = ko.computed(function () {
        var diff = Math.abs(new Date(), this.date());
        return (((diff / 1000) / 60) / 60) / 24;
    }, this);
}

...
Sign up to request clarification or add additional context in comments.

2 Comments

Excellent, this is exactly what I was after. Appreciated thanks, for anyone interested, the full working version of that fiddle is here: jsfiddle.net/skt2q/3
No problem. Btw, you can create a new Calendar by JSON like this: new Calendar($.parseJSON(json)).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.