简体   繁体   中英

Loading data from ajax breaks functionality

I am trying to create a real-time filter on a table using knockoutjs. I have managed to get everything to work when I statically create the observable array like this:

$(function() {
  var assets = [
    {id: "1", poster: "Pic010.jpg", name: "Asset1", category: "category1", type: "Movie", popup: "1" },
    {id: "2", poster: "Pic06.jpg", name: "Asset2", category: "category2", type: "Movie", popup: "2" },
    {id: "3", poster: "Pic04.jpg", name: "Asset3", category: "category1", type: "Pop-up", popup: "3" },
    {id: "4", poster: "Pic07.jpg", name: "Asset4", category: "category2", type: "Pop-up", popup: "4" },
    {id: "5", poster: "Pic011.jpg", name: "Asset1", category: "category3", type: "Promo", popup: "5" }
  ];

  var viewModel = {
    assets: ko.observableArray(assets),

    query: ko.observable(''),

    search: function(value) {
      viewModel.assets.removeAll();
      for(var x in assets) {
        if(assets[x].name.toLowerCase().indexOf(value.toLowerCase()) >= 0) {
          viewModel.assets.push(assets[x]);
        }
      }
    }
  };

  viewModel.query.subscribe(viewModel.search);

  ko.applyBindings(viewModel);
});

JSFiddle of working code: http://jsfiddle.net/7ZLdk/1/

Now when I try to load the observable array data via ajax like this:

var assets = [];
    $.ajax({
        url: '/Assets/getJson/',
        type: "GET",
        dataType: 'json',
        success: function (data) {
            console.log(data);
            viewModel.assets(data);
        }
    });

the data is displayed correctly in the table when the page is loaded, but when I start typing in the search input, all the data disappears.

I would appreciate it if someone could explain what I am doing incorrectly in the AJAX load? TIA

I have resolved the problem. I was not populating the assets array. This is the updated ajax call:

 $.ajax({
        url: '/Assets/getJson/',
        type: "GET",
        dataType: 'json',
        contentType: "application/json",
        success: function (data) {
            console.log(data);
            viewModel.assets(data);
            assets = data; // THIS WAS MISSING
        }
    });

You are better off creating a ViewModel function, so the viewmodel only accesses data within itself:

$(function() {
  $.ajax({
        url: '/Assets/getJson/',
        type: "GET",
        dataType: 'json',
        contentType: "application/json",
        success: function (data) {
            console.log(data);
            var viewModel = new ViewModel(data);

            ko.applyBindings(viewModel);
        }
    });
});

function ViewModel(assets) {
  var self = this;

  self.assets = ko.observableArray(assets);
  self.allAssets = assets;
  self.query = ko.observable('');

  self.search = function(value) {
      self.assets.removeAll();
      for(var x in self.allAssets) {
        if(self.allAssets[x].name.toLowerCase().indexOf(value.toLowerCase()) >= 0) {
          self.assets.push(self.allAssets[x]);
        }
      }
  };

  self.query.subscribe(self.search);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM