Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ObservableArray.RemoveAll() empties the concated objects in a different variable

In my KnockoutJS view model logic I have an observable array of currently displayed objects (project view models): self.currentProjects. Depending on an item filter setting (user chooses project types dynamically) self.currentProjects holds different objects that a UI is bound to.

At some point, where I need to load different projects into the view, I need to empty the currentProjects and put different set of models into it. I do this by calling self.currentProjects.removeAll(); The problem is when I call it, another observable array self.ProjectModels that should hold the reference to the same set of models also appears to be emptied up. How should I manage objects in an observable array, so that removal from one array doesn't cause the other to become empty.

Here is a manipulation related code:

    //Another menu item is selected
    self.selectItem = function(newId) {
        self.selectedItemId(newId);
        self.currentProjects.removeAll(); //This is the point where self.ProjectModels also looses model references
        var someProjectsLoaded = false;
        jQuery.each(self.projectModels, function (i, val) {
            if (val.type == self.selectedItemId()) {
                self.currentProjects(val.models);
                var projectsPerPage = parseInt($('#ProjectsPerPage').val(), "10");
                self.page(val.models.length / projectsPerPage);
                someProjectsLoaded = true;
            }
        });
        if (!someProjectsLoaded) {
            self.page(1);
            self.LoadMoreProjects();
        }
    };

    self.LoadMoreProjects = function() {
        var getProjectsUrl = $("#GetNextProjectsUrl").val();
        $.ajax({
            url: getProjectsUrl,
            data: {
                page: parseInt(self.page(), "10"),
                type: self.selectedItemId()
            },
            beforeSend: function () {
                //$("#ajaxload").show();
            },
            success: function (result) {
                var newlyAddedModelsArray = jQuery.map(result, function (val, i) {
                    var vm = new ProjectViewModel(val, self);
                    self.currentProjects.push(vm);
                    return vm;
                });
                self.page(parseInt(self.page(), "10") + 1);
                var typeAlreadyInChache = false;
                jQuery.each(self.projectModels, function (i, val) {
                    if(val.type == self.selectedItemId()) {
                        val.models = val.models.concat(newlyAddedModelsArray); //HERE IS WHERE I SUSPECT A COPY BE REFERENCE TAKES PLACE
                        typeAlreadyInChache = true;
                    }
                });
                if(!typeAlreadyInChache) {
                    self.projectModels.push({ type: self.selectedItemId(), models: newlyAddedModelsArray });
                }
            },
            error: function () {
                $("#error").show();
            }
        });
    };
like image 291
Maxim V. Pavlov Avatar asked Dec 20 '22 12:12

Maxim V. Pavlov


1 Answers

Calling removeAll empties the underlying array and your two observables appear to have a reference to the same array.

An easy choice is to set currentProjects to an empty array rather than calling removeAll.

self.currentProjects([]);

Now, the original array will remain as it was.

like image 58
RP Niemeyer Avatar answered Jan 17 '23 19:01

RP Niemeyer