11

I am getting a large array of objects through ajax and if the array has data then it will be passed to ImportObservableListItems in my viewmodel:

        success: function (data) {
            debugger 
            if (data.length > 0) {

            ReadingList.ImportObservableListItems(data);

            } 

in the viewmodel I would like to add each object to an observable array but I need the properties of each object to be observable. however if the array contains a large number of objects then the browser crashes. is there any way I could prevent it?

self.ImportObservableListItems = function (data) {
            $.each(data, function(index, item) {
                var newListItem = {
                    MediaID: ko.observable(item.MediaID),
                    MediaName: ko.observable(item.MediaName),
                    MediaTypeID: ko.observable(item.MediaTypeID),
                    MediaTypeName: ko.observable(item.MediaTypeName),
                    Group1: ko.observable(item.Group1),
                    Group2: ko.observable(item.Group2),
                    Group3: ko.observable(item.Group3),
                    Group4: ko.observable(item.Group4),
                    Group5: ko.observable(item.Group5)
                };
                ReadingList.ReadingListItems.push(newListItem);
            });
        };
1
  • 2
    how many is "a large number of objects"? Commented Apr 19, 2013 at 13:37

1 Answer 1

25

You can reduce the churn by pushing all the items at once (push accepts multiple items):

var items = $.map(data, function (item) {
    return {
        MediaID: ko.observable(item.MediaID),
        MediaName: ko.observable(item.MediaName),
        MediaTypeID: ko.observable(item.MediaTypeID),
        MediaTypeName: ko.observable(item.MediaTypeName),
        Group1: ko.observable(item.Group1),
        Group2: ko.observable(item.Group2),
        Group3: ko.observable(item.Group3),
        Group4: ko.observable(item.Group4),
        Group5: ko.observable(item.Group5)
    };
});

ReadingList.ReadingListItems.push.apply(ReadingList.ReadingListItems, items);

This will cause only a single notification to go out when all the items have been added, instead of once per item.

Sign up to request clarification or add additional context in comments.

2 Comments

can I ask you if the same performance benefits could be achieved by using something like: self.customObsArray($.map(data, function (item) { return new CustomModel(item); })); or even better by using ko.utils.arrayMap for removing the jquery dependency
@Simone sure just keep in mind that your suggestion would be replacing the existing array of items with a new array of items, which is different semantically than what the OP wanted (they wanted to add items to an existing array).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.