Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

knockout.js Multiple mapping in nested objects

I'm new with knockout.js and I don't know how to do multiple mapping with my object. That's my data from the server :

var persons = {
    'value': [
        {
            "id": "1",
            "civility": "Mr.",
            "firstname": "john",
            "lastname": "doe",
            "phone": "00 00 00 00 00",
            "email": "[email protected]",
            "contract": [
                {
                    "id": "1",
                    "gamme": "Gamme 1",
                    "formula": "Formula 1"
                },
                {
                    "id": "2",
                    "gamme": "Gamme 2",
                    "formula": "Formula 2"
                }
            ]
        }
    ]
}

I do a first mapping on the whole object and ko.computed some datas :

var person_mapping = {
        'value': {
            create: function (options) {
                if (options.data != null) {
                    return new myPersonModel(options.data);
                }
            }
        }
    }

var myPersonModel = function (data) {
        ko.mapping.fromJS(data, {}, this);

        this.fullName = ko.computed(function () {
            return this.civility() + ' ' + this.lastname() + ' ' + this.firstname();
        }, this);
    }

After executing this, I get what I want for the first part :

self.dataModel = ko.mapping.fromJS(persons, person_mapping);

But now, I want to do the same thing with the contract array inside the persons object, that is to say apply a mapping and do some ko.computed like this :

var contract_mapping = {
            'contract': {
                create: function (options) {
                    if (options.data != null) {
                        return new myContractModel(options.data);
                    }
                }
            }
        }

var myContractModel = function (data) {
            ko.mapping.fromJS(data, {}, this);

            this.contractName = ko.computed(function () {
                return this.gamme() + ' ' + this.formula();
            }, this);
        }

But I don't know how to apply my second mapping, nothing seems to work.

like image 747
Fabien G Avatar asked Oct 18 '22 08:10

Fabien G


1 Answers

You can apply your second mapping in the first line of myPersonModel. You can keep nesting the mapping strategies in every constructor you're using.

var myPersonModel = function(data) {
  ko.mapping.fromJS(data, contract_mapping, this);
  /* ... */
};

var persons = {
  'value': [{
    "id": "1",
    "civility": "Mr.",
    "firstname": "john",
    "lastname": "doe",
    "phone": "00 00 00 00 00",
    "email": "[email protected]",
    "contract": [{
        "id": "1",
        "gamme": "Gamme 1",
        "formula": "Formula 1"
      },
      {
        "id": "2",
        "gamme": "Gamme 2",
        "formula": "Formula 2"
      }
    ]
  }]
}

var contract_mapping = {
  "contract": {
    create: function(options) {
      return new myContractModel(options.data);
    }
  }
}

var person_mapping = {
  'value': {
    create: function(options) {
      if (options.data != null) {
        return new myPersonModel(options.data);
      }
    }
  }
}

var myContractModel = function(data) {
  ko.mapping.fromJS(data, {}, this);
  this.type = "myContractModel";
};

var myPersonModel = function(data) {
  ko.mapping.fromJS(data, contract_mapping, this);

  this.fullName = ko.computed(function() {
    return this.civility() + ' ' + this.lastname() + ' ' + this.firstname();
  }, this);
}

console.log(
  ko.mapping.fromJS(persons, person_mapping)
    .value()[0]
    .contract().map(x => x.type)
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
like image 105
user3297291 Avatar answered Oct 21 '22 01:10

user3297291