Question

I'm not if the title explains what I need to achieve or not but I can change it later if some has a better suggestion.

I'm using KO to manage a whole bunch of data on the client side.

Here's the basic.

  1. I have a list of training sessions
  2. Each has a list of training session parts
  3. Each training session parts are referencing items kept in other lists. For example, I have a list of activities (ex: biking, running, swimming, etc.)
  4. Each activity is identified by an ID which is used in the training session parts to identify which activity was used for a particular session.

Now, all these list are stored as observable arrays, and each member of the lists are observables (I use KO.Mapping to map the JSON coming from the server)

When I display a training session in my UI, I want to display various information coming from various lists

Duration: 1h30
Activity: Biking
Process: Intervals

The only information I have in order to link the training session to its component is an ID which is fine. What I'm not sure is how to data-bind the name (text) of my activity to a <p> or <div> so that the name will change if I edit the activity (by using some functionality of the application).

The training session only has the ID to identify the activity, so I don’t know how to bind the name of the activity based on its ID.

Hopefully this makes senses and someone can help me figure it out. I found lots of info on how to bind to observable array but nothing addressing ID and linked information.

Was it helpful?

Solution

The easiest way would probably be to make your own constructors and link the data by hand. You can use mapping if you really want to, but you'll basically have to do the same manual linking, only in a more verbose format.

This is the fiddle with the example implementation: http://jsfiddle.net/aKpS9/3/

The most important part of the code is the linking, you have to take care to create the activity objects only once, and use the same objects everywhere, as opposed to creating new activity objects for the parts.

var TrainingSession = function(rawData, actualActivities){
    var self = this;
    self.name = ko.observable(rawData.name);
    self.parts = ko.observableArray(ko.utils.arrayMap(rawData.parts, function(rawPart){
        return ko.utils.arrayFirst(actualActivities(), function(ac){
            return ac.ID() == rawPart.ID;
        })
    }));
}

var Activity = function(rawData){
    var self = this;
    self.ID = ko.observable(rawData.ID);
    self.name = ko.observable(rawData.name);
}

var MainVM = function(rawData){
    var self = this;
    //first create an array of all activities
    self.activities = ko.observableArray(ko.utils.arrayMap(rawData.activities, function(rawAc){
        return new Activity(rawAc);
    }));

    self.trainingSessions = ko.observableArray(ko.utils.arrayMap(rawData.trainingSessions, function(session){
        return new TrainingSession(session, self.activities);
    }));

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top