Knockout load JSON from AJAX call

I’m currently creating a list of items with pager and filter.
The base I used is this: http://jsfiddle.net/JTimperley/pyCTN/13/

But I need to load the data from AJAX, and the response is JSON.

Read More

The model which recieves the data on creation:

function CustomerPageModel(data)
{
  if (!data)
  {
    data = {};
  }

  var self = this;
  self.customers = ExtractModels(self, data.customers, CustomerModel);

  var filters = [
    {
      Type: "text",
      Name: "Name",
      Value: ko.observable(""),
      RecordValue: function(record) { return record.name; }
    },
    {
      Type: "select",
      Name: "Status",
      Options: [
        GetOption("All", "All", null),
        GetOption("None", "None", "None"),
        GetOption("New", "New", "New"),
        GetOption("Recently Modified", "Recently Modified", "Recently Modified")
      ],
      CurrentOption: ko.observable(),
      RecordValue: function(record) { return record.status; }
    }
  ];
  var sortOptions = [
    {
      Name: "ID",
      Value: "ID",
      Sort: function(left, right) { return left.id < right.id; }
    },
    {
      Name: "Name",
      Value: "Name",
      Sort: function(left, right) { return CompareCaseInsensitive(left.name, right.name); }
    },
    {
      Name: "Status",
      Value: "Status",
      Sort: function(left, right) { return CompareCaseInsensitive(left.status, right.status); }
    }
  ];
  self.filter = new FilterModel(filters, self.customers);
  self.sorter = new SorterModel(sortOptions, self.filter.filteredRecords);
  self.pager = new PagerModel(self.sorter.orderedRecords);
}

The binding works well if I simply echo json value for events
However, when I call my AJAX-function and new data is added, the model won’t update.

var data = {
  action: 'load_data'
};
jQuery.post(ajaxurl, data, function(response) {
  var json = JSON.parse(response);
  var models = ExtractModels(_customerPageModel, json, CustomerModel);
  _customerPageModel.customers = models;
});

Related posts

Leave a Reply

1 comment

  1. The problem is you are replacing the _customerPageModel.customers variable.

    Knockout data-binding works by using some special properties – observables and observableArrays.

    Anything that you need to be bound to the DOM must be observable.

    Therefore, you should probably transform your customers into a observableArray, and push to it when you have new data. For example:

    function CustomerPageModel(data)
    {
      (...)    
      var self = this;
      self.customers = ko.observableArray(ExtractModels(self, data.customers, CustomerModel));
      (...)
    }
    

    And when receiving data:

    var data = {
      action: 'load_data'
    };
    jQuery.post(ajaxurl, data, function(response) {
      var json = JSON.parse(response);
      var models = ExtractModels(_customerPageModel, json, CustomerModel);
      _customerPageModel.customers.push.apply(_customerPageModel.customers, models);
    });
    

    Take a look at the observableArray docs: http://knockoutjs.com/documentation/observableArrays.html

    Note that I am using the push method to add all new data to the end of the array. You may wish to completely overwrite the array. If so, it’s even simpler:

    _customerPageModel.customers(models);
    

    In this way, your customers array is replaced by the new models array.