Throttling with knockout mapping plug

2019-05-10 21:51发布

I'm having a problem with the knockout-mapping plugin with IE8. Our situation is that we send over all the possible records that can be displayed to the client. Then we handle all paging and filtering on the client side for a responsive system.

Currently, we are sending of a list of 250 records to display in a jQuery template based grid via jQuery ajax. When we call ko.mapping.fromJS (not the fromJSON function) to map the objects, we are getting a "Script taking too long" message from IE8. Doesn't occur in FF and Chrome as their java script executes much faster.

Is there a straight forward way to throttle the mapping? This is a long term issue as we can have a situation where we have close to 1000 records to send to client.

3条回答
趁早两清
2楼-- · 2019-05-10 22:31

We had the same problem too. Our viewmodel had one too many computed observables and it was causing the script to run more slowly. Removing unnecessary subscribles might save you from this problem.

查看更多
仙女界的扛把子
3楼-- · 2019-05-10 22:35

I know this isn't an ideal answer, but if your situation allows it, you can always just not map the inner items. Ex. If your ajax call is returning 1000 people and you want your UI to update and show all of those people, you can have your viewmodel have an observableArray of raw people js objects (and not their ko mapped equivalent). If you add or remove items from your observableArray, it'll show correctly on the UI, but it will not help you if need to subscribe to all of the property change events on all of each person's properties.

Typically when I'm pulling this many items, it is for reporting and so I don't need to edit the items themselves, but do need to add/remove rows from the report depending on filter criteria.

查看更多
Summer. ? 凉城
4楼-- · 2019-05-10 22:44

IE is a naughty little.....isn't it.

When doing data binding with javascript if there is going to be a significant UI update I do something like the following.

function ajaxCallback(listOfDataItems){

  var addToUiFunction = function(item){
     // add it to the ko.observable array which is data bound to the UI
     myDataBoundArray.push(item);
  };

  for (var i = 0, arrayLength = listOfDataItems.length; i < arrayLength; i++){
    var temp = listOfDataItems[i];

    //create an immediately executing function to close around
    //the item that returns a function to call at a later date.
    var tempFunction = (function(){
      var item = temp;
      return function() { addToUiFunction(item) };
    })();

    setTimeout(tempFunction, 0);

  }
}

What has happened here is that I only add one item to the UI at once. I use setTimeout with a delay of 0 to defer the execution of an individual add until the current call finishes. This means very short units of work that won't time out your browser.

p.s. the code is a little dodgy, it's just trying to illustrate a point.

查看更多
登录 后发表回答