1
votes

Let's take below as my MVC model class:

public class Candidate
{
    public string FirstName { get; set; }
    public string LastName { get; set; }        
    public string Email { get; set; }
    public int Experience { get; set; }
    public List<Technology> Technologies { get; set; }
}

public class Technology
{
    public string Technology { get; set; }
    public int ExperinceInMonths { get; set; }
} 

Now, I have a web api method which returns this modal data:

public class CandidateController : ApiController
{
    // GET api/Candidate
    public IEnumerable<Candidate> Get()
    {
        CandidateServiceClient client = new CandidateServiceClient();

        List<Candidate> candidateData = client.GetCandidateData();

        if (candidateData == null || candidateData.Count() == 0)
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NoContent));

        return candidateData.AsEnumerable(); 
    }
     ...

Using Knockout let's say I have javascript something like this:

         $.get(url, function (result) {
           candidateViewModel.candidates(result);
           ko.applyBindings(candidateViewModel); 
       }); 
    });
 var candidateViewModel = { candidates:  ko.observableArray([])};

With this background, my question is how to construct knockout viewmodel which has nested collection(s) ? (like Technology collection in this example.)

Looking for something like..

var myViewModel = { firstName: ko.observable(''), lastName: ko.observable(''), .. };

Any help is greatly appreciated...

2

2 Answers

3
votes

In my opinion, you should use ko.mapping.fromJS, just in case the model goes very complex, you do not need to change your view model.

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

0
votes

The output on this is super messy, but it illustrates the idea. The thing here is to have Candidate and Technology models in your javascript, and use arrayMap to call their contructors. Here is the fiddle. Note: the models don't need to have observables properties if you don't plan on changing their values.

Models:

var Technology = function(name, monthsExperience){
    this.name = ko.observable(name);
    this.monthsExperience = ko.observable(monthsExperience);
};

var Candidate = function(data){

    this.firstName = ko.observable(data.FirstName || '');
    this.lastName = ko.observable(data.LastName || '');
    this.email = ko.observable(data.Email || '');
    this.experience = ko.observable(data.Experience || '');

    this.technologies = ko.observableArray(ko.utils.arrayMap(data.Technologies || [],
        function(i){
            return new Technology(i.Technology, i.ExperinceInMonths);
        }));
};

Main Viewmodel:

var App = function(initialData){
    this.candidates = ko.observableArray(ko.utils.arrayMap(initialData|| [],
        function(i){
            return new Candidate(i);
        }));
};