How to Clear Contents of an observableArray That was Populated from Previous Visits to a View
Asked Answered
G

4

49

I have a Single Page Application that uses knockout for the data binding. The CAApproval.html view in my single page application has an observeablearray named AllCertificates in the viewmodel code. It populates fine on the page. When you navigate away from the view by clicking a link in the navigation.html part of the page and then return to CAApproval page, the values from the previouse visit are still in the AllCertificates observableArray and therefore are displayed on the CAApproval view.

I need to clear the contents of the AllCertificates observablearray each time a user returns to the CAApproval page that uses that observablearray so that if a user leaves the page and comes back, the contents of the observablearray are null, and therefore no data is displayed on the screen. Here are the highlights of my viewmodel code-

define(['services/logger', 'durandal/system', 'durandal/plugins/router', 'services/CertificateDataService','controls/Lucas'],

       function(logger, system, router, CertificateDataService) {
        var allCertificates = ko.observableArray([]);

    var activate = function () {
            // go get local data, if we have it
            return SelectAllCerts(),SelectMyCerts(), GetCertificateDetails(), GetDDABankNums();
            };
        var vm = {
            activate: activate,
            allCertificates: allCertificates,
    SelectAllCerts: SelectAllCerts

        });

    return vm;

    function SelectAllCerts() {
                return CertificateDataService.getallCertificates(allCertificates);
        }
    });

How do I clear the contents of an observablearray each time the page a user comes to that page (NOT when navigating within the page itself, only clear the observablearray when the user comes from a seperate page)?

Gagnon answered 5/9, 2013 at 14:4 Comment(0)
H
44

Just set it equal to nothing (allCertificates([])) in your activate function, which is called each time your view model loads -

function(logger, system, router, CertificateDataService) {
    var allCertificates = ko.observableArray();

var activate = function () {
    allCertificates([]);
    // go get local data, if we have it
    return SelectAllCerts(),SelectMyCerts(), GetCertificateDetails(), GetDDABankNums();
};

var vm = {
    activate: activate,
    allCertificates: allCertificates,
    SelectAllCerts: SelectAllCerts
});
Heigho answered 5/9, 2013 at 14:6 Comment(4)
Perfect! Thanks. Still getting use to knockout.Gagnon
Wow. I've been looking for a similar answer for over 2 days now. Thank you so much for this!Gasp
DO NOT USE: this will destroy the current observable array and cause any functions already referencing that Array to looks their auto-magic connection for updates and listeningVariegated
Use below solution of: self.mycertificates.removeAll();Variegated
D
90

Also knockout observableArray has interesting methods. Call removeAll to clear all items.
Look at official site observable array manual.

self.mycertificates = ko.observableArray(['C1', 'C2']);  
self.mycertificates.removeAll();
Doretheadoretta answered 30/1, 2014 at 23:59 Comment(0)
H
44

Just set it equal to nothing (allCertificates([])) in your activate function, which is called each time your view model loads -

function(logger, system, router, CertificateDataService) {
    var allCertificates = ko.observableArray();

var activate = function () {
    allCertificates([]);
    // go get local data, if we have it
    return SelectAllCerts(),SelectMyCerts(), GetCertificateDetails(), GetDDABankNums();
};

var vm = {
    activate: activate,
    allCertificates: allCertificates,
    SelectAllCerts: SelectAllCerts
});
Heigho answered 5/9, 2013 at 14:6 Comment(4)
Perfect! Thanks. Still getting use to knockout.Gagnon
Wow. I've been looking for a similar answer for over 2 days now. Thank you so much for this!Gasp
DO NOT USE: this will destroy the current observable array and cause any functions already referencing that Array to looks their auto-magic connection for updates and listeningVariegated
Use below solution of: self.mycertificates.removeAll();Variegated
D
4

For Jeremy T (not enough space in comment).
First reason and absolutely enough for me is existence of publicly available API for desired purpose.

But to estimate performance you can check source. "observableArray" is also "observable" with additional functions injected into object.

So initialization looks like this:

ko.observableArray = function (initialValues) {
    initialValues = initialValues || [];

    if (typeof initialValues != 'object' || !('length' in initialValues))
        throw new Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");

    var result = ko.observable(initialValues);
    ko.utils.extend(result, ko.observableArray['fn']);
    return result.extend({'trackArrayChanges':true});
};

ko.observable = function (initialValue) {
    var _latestValue = initialValue;

    function observable() {
        if (arguments.length > 0) {
            // Write

            // Ignore writes if the value hasn't changed
            if (!observable['equalityComparer'] || !observable['equalityComparer'](_latestValue, arguments[0])) {
                observable.valueWillMutate();
                _latestValue = arguments[0];
                if (DEBUG) observable._latestValue = _latestValue;
                observable.valueHasMutated();
            }
            return this; // Permits chained assignments
        }
        else {
            // Read
            ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation
            return _latestValue;
        }
    }
    if (DEBUG) observable._latestValue = _latestValue;
    ko.subscribable.call(observable);
    observable.peek = function() { return _latestValue };
    observable.valueHasMutated = function () { observable["notifySubscribers"](_latestValue); }
    observable.valueWillMutate = function () { observable["notifySubscribers"](_latestValue, "beforeChange"); }
    ko.utils.extend(observable, ko.observable['fn']);

    ko.exportProperty(observable, 'peek', observable.peek);
    ko.exportProperty(observable, "valueHasMutated", observable.valueHasMutated);
    ko.exportProperty(observable, "valueWillMutate", observable.valueWillMutate);

    return observable;
}

And remove all elements looks like this:

'removeAll': function (arrayOfValues) {
        // If you passed zero args, we remove everything
        if (arrayOfValues === undefined) {
            var underlyingArray = this.peek();
            var allValues = underlyingArray.slice(0);
            this.valueWillMutate();
            underlyingArray.splice(0, underlyingArray.length);
            this.valueHasMutated();
            return allValues;
        }
        // If you passed an arg, we interpret it as an array of entries to remove
        if (!arrayOfValues)
            return [];
        return this['remove'](function (value) {
            return ko.utils.arrayIndexOf(arrayOfValues, value) >= 0;
        });
    }
Doretheadoretta answered 30/6, 2014 at 20:5 Comment(0)
J
1

to initialize an array variable

self.allCertificates = ko.observableArray([]) 

to remove all the value of array

self.allCertificates.removeAll()
Jacobson answered 5/4, 2020 at 4:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.