Pekka Ylenius
Pekka Ylenius

Reputation: 498

Knockout mapping + computed child elements + "mapping reload" fails

I wish to use Knockout mapping to generate ViewModel.

var viewModel = ko.mapping.fromJS(data);

After creating ViewModel I would like to add computed text element.

for (var i = 0; i < viewModel.Packages().length; i++) {
    var pack = viewModel.Packages()[i];
    pack.packageClass = ko.computed(function() {
        return this.Height() * this.Depth() * this.Width()
    }, pack);
}

Bind the page.

ko.applyBindings(viewModel);

Page is working fine in this state...

But now user would like to "save" and "reload" page. This would be done using mapping feature which updates ViewModel with new data.

data = ko.mapping.toJSON(viewModel);

But it is not possible to add again those computed fields before rebinding page. And I will get error that computed element is not found (anymore).

ko.mapping.fromJS(data, viewModel);

Am I doing something totally wrong?

Everything works fine without computed fields or without reloading ViewModel...

Update: Fiddle updated to work like in solution.

Fiddle sample

Upvotes: 0

Views: 497

Answers (1)

Anders
Anders

Reputation: 17564

Create a explicit ViewModel

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

    this.packageClass = ko.computed(function() {
        return this.Height() * this.Depth() * this.Width()
    }, this);
};

then use mappign options like this

var mapping = {
   Packages: {
      create: function(options) {
         return new PackageViewModel(options.data);
      }
   }
};

ko.applyBindings(ko.mapping.fromJS(data, mapping));

Upvotes: 1

Related Questions