简体   繁体   中英

AngularJS - Need to clear javascript object on controller change

I am new to AngularJs. Currently I have a directive that populates a JavaScript object called keyListeners . Now this object gets populated and serves its purpose fine the first time I come to the page on which it is used. Unfortunately when I navigate away from the page and then come back to it I see errors in my console like

"angular.min.js:116 More than one amtAltKey found for key 'A' "

Then the functionality of the page starts to break.

I know I could theoretically check for the existence of the element in keyListeners, before adding it to the object. However, instead of doing that I would like to run some logic to clear out keyListeners on control change. My directive that actually populates keyListeners is below. How can I clear this out every time the controller/page changes.

app.directive("amtAltKey", function () {
    return {
        link: function (scope, elem, attrs) {
            var altKey = attrs.amtAltKey.toUpperCase();
            if(keyListeners[altKey] !== undefined) { throw 'More than one amtAltKey found for key \''+ altKey + '\''; }
            if (altKey === '') { throw "Alt Key value key must be given"; }
            var el = elem[0];
            if (!el.hasChildNodes()) { throw 'amtAltKey element must have child text'; }
            if(el.firstChild.nodeName !== '#text') { throw 'amtAltKey element\'s child must be text'; }
            var text = el.innerText;
            var textUpper = text.toUpperCase();
            var indexOfKey = textUpper.indexOf(altKey);
            if (indexOfKey === -1) { throw 'amtAltKey for \'' + altKey + '\' was not found in element\s text; ' + text; }
            var newText = text.replace(new RegExp(attrs.amtAltKey), '<u>' + attrs.amtAltKey + '</u>');
            el.innerHTML = newText;
            keyListeners[altKey] = el;
        }
    };
});

Is keyListeners currently a global? If so, that's the problem. It's not being garbage collected when the directive is blown up, when switching screens. Just add do something like...

var keyListenteners = {};

...in your directive.

Or, better, move keyListeners in to their own service or factory and include it. Something like:

angular.module("myApp").factory("keyListeners", function() {
    return {
      // your properties here
    };
});

This will act like a data singleton, kind of like your global, between your different controllers. A change made to one will be reflected in the others. That of course is the very problem you want to avoid, so you could add a clear() method to this singleton and call it every time your route changes or even in your controller constructor.

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