简体   繁体   中英

$destroy is not being called when element is removed from DOM

I have a directive that's added to forms, and I need to know when a form is removed from the DOM. I'm trying to detect it with the $destroy event, but when I call .remove() on an element the $destroy event is not triggered.

Am I doing this wrong? Is there a correct way to tell when it's removed from the DOM?

Relevant code:

The HTML:

<form id="myform" form-watch>

In the controller:

var form = document.getElementById('myform');
// DOES NOT trigger $destroy
form.remove();

// DOES trigger $destroy
//angular.element(form).scope().$destroy();

The directive:

app.directive('formWatch', function () {
  return {
    restrict: 'A',
    link: function(scope, element) {
        scope.$on('$destroy', function() {
            alert('destroyed');
        });
    }
  };
});

Here's a plunker

EDIT: Here's a much more accurate picture of what I'm working with: new plunker

The scope destruction is not connected to the DOM automatically - so if you want to remove a directive manually, IMO the correct way is to call $destroy() and then remove any related dom explicitly.

So I would move the element's removal to the $destroy callback and trigger it with the code you already have

angular.element(form).scope().$destroy();

and in your directive

scope.$on('$destroy', function() {
    element.remove();
});

HTH

I'm not so sure that what you are really concerned with is the actual destroy event itself, but rather a way in the app to know when the form exists or not.

This should be monitored through the controllers and services in the app.

The issue I think is that there is dom manipulation going on that shouldn't be there ... By using proper scope models and designing views to be solely driven by scope models angular should be doing almost all of the dom manipulation , if not all of it.

Following example acheives the alert you want by wrapping form in it's own controller and using ng-if and a scope variable to determine whether form exists or not:

app.controller('MainCtrl', function($scope) {
  $scope.showForm = true;
});

app.controller('FormCtrl', function($scope) {
  $scope.$on('$destroy', function() {
    alert('destroyed');
  });
});

HTML:

<body ng-controller="MainCtrl">
  <!-- form has it's own controller -->
  <form ng-if="showForm" ng-controller="FormCtrl"></form>

 <!-- button in MainCtrl scope -->
 <button ng-click="showForm = !showForm">Toggle form</button>

Whenever form is removed by ng-if the FormCtrl scope is destroyed and the $destroy event is triggered. However watching the scope variable that determines form existence is likely what you are really after

DEMO

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