Angular - How can I remove from the DOM an element I have used $compile on?

42,944

Solution 1

The solution for this problem is creating a new child scope. All bindings with parent scope work because of scope Inheritance. When I need to change the content, I simply destroy the child scope, avoiding memory leaks.

I've also made and getter and setter methods for the child scope to avoid poluting que parent scope, in case the other content uses disposable variables

Solution 2

To manually remove the element do an element.remove(). Sounds like you also want to destroy the scope of your compiled element so you can do that too by doing scope.$destroy(); or $scope.$destroy(); depending on if you're in a directive or not.

http://docs.angularjs.org/api/ng.$rootScope.Scope#$destroy

Solution 3

Thanks for you good solution. I've just posted some implement code

.directive('modal', function($templateCache, $compile) {
    return function(scope, element, attrs) {
        var currentModalId = attrs.modalId;
        var templateHtml = $templateCache.get(attrs.template);
        var modalScope, modalElement;

        scope.$on('modal:open', function(event, modalId) {
            if(modalId == null || currentModalId === modalId) {
                openModal();
            }
        });

        scope.$on('modal:close', function(event, modalId) {
            if(modalId == null || currentModalId === modalId) {
                closeModal();
            }
        });

        function openModal() {
            // always use raw template to prevent ng-repeat directive change previous layout
            modalElement = $(templateHtml);

            // create new inherited scope every time open modal
            modalScope = scope.$new(false);

            // link template to new inherited scope of modal
            $compile(modalElement)(modalScope);

            modalElement.on('hidden.bs.modal', function() {
                if(modalScope != null) {
                    // destroy scope of modal every time close modal
                    modalScope.$destroy();
                }
                modalElement.remove();
            });

            modalElement.modal({
                show: true,
                backdrop: 'static'
            });
        }

        function closeModal() {
            if(modalElement != null) {
                modalElement.modal('hide');
            }
        }
    };
});
Share:
42,944
Nickydonna
Author by

Nickydonna

Updated on July 09, 2022

Comments

  • Nickydonna
    Nickydonna almost 2 years

    What I need is the functionality of two ng-views. Because I can't I want to change the innerHTML of something and compile it. The problem I have is when I change the content again, I can compile, but does angular remove the binding on it's own, or I do I have to do it manually, if so, how?

    EDIT: Explaining

    I want to make a modal, whose content I can change and bind to different scopes (hence the $compile). But I don't want to destroy the whole modal, just some of its content, and change to another. My main doubt is if by removing some compiled HTML it can lead to memory leaks.

    SOLVED

    For this problem, I created a new child scope (with $new) and destroyed it whenever I changed the content. Thanks for everything

  • Nickydonna
    Nickydonna about 11 years
    Maybe I don't undestand something of Scope, but if I destroy the scope of an element, which has to be done at Controller level, I would destroy everything in it, wouldn't I?? I just want to remove some of the elements, and their binding
  • Nickydonna
    Nickydonna about 10 years
    actually nowadays I'm using angular-ui.github.io/bootstrap, they have an amazing collections of tools, and the modal components is crazy good.
  • Duy Tran
    Duy Tran about 10 years
    yeah, I also agree with you
  • Andi Giga
    Andi Giga over 8 years
    Am I understanding this right, that if I don't create this new scope modalScope = scope.$new(false); and just $compile the element to scope that I'm adding garbage to my scope with every new modal.
  • Duy Tran
    Duy Tran over 7 years
    Yep, if you don't create a new child scope, you will use compile modal with parent scope and maybe modal controller will add garbage or override methods of scope