How to "destroy" a directive and replace it with new values

I have 2 sets of arrays. the first set is the default. when user clicks on next button i need to update new set. I can do it.

But the previous set also exists. I don't know how to properly remove this, and define new values. I am looking for a way that deletes event listner

by deleting DOM

. and there shouldn't be a memory leak either.

here is my js:

var myApp = angular.module('myApp', []);

myApp.controller('main', function ($scope) {

  $scope.values = [{"name":"one", "num" : 1}, {"name":"two", "num" : 2}, {"name":"three", "num" : 3}];

  $scope.next = function () {
    $scope.index = 4;
    $scope.values = [{"name":"four", "num" : 4}, {"name":"five", "num" : 5}, {"name":"six", "num" : 6}];

  }

  $scope.index = 0;

  $scope.update = function (value) {
    console.log("clicked " + value.num);
    $scope.index = value.num;
    $scope.$apply();
  }

});

myApp.directive("newArray", function ($compile) {

  return {

    scope : {
      value : "=",
      index : "=",
      update:"&"
    },

    link : function (scope, element, attrs) {

      var getTemplate = function (value, index) {

        switch(index) {

          case 0 :
            return '<div ng-click="update()">I am here {{index}} {{value.name}}</div>'
            break;

            case 1 :
            return $('<div />', {
              class:'blue',
              html : "<h1>testing{{index}} {{value.name}}</h1>",
              click : function () {
                scope.update({num: scope.value.num});
              }
            });
            break;

            case 2 :
            return $('<div />', {
              class:'green',
              html : "<h1>testing{{index}} {{value.name}}</h1>",
              click : function () {
                scope.update({num: scope.value.num});
              }
            });
            break;

        }

      }

      element.html(getTemplate(scope.value, scope.index));
      $compile(element.contents())(scope);
      element.replaceWith(element.contents());

    }

  }

});

      

Live Demo

mine is updated plnkr

. can help me in the future.

+3


source to share


1 answer


For such a different requirement, I won't use a dedicated scope directive which will mess up. Because you want to use DOM directive replace directive with directive template. Another reason why you are using ng-repeat

in your directive that does not support the DOM structure properly, as you are replacing the DOM directive with the newly created DOM. Instead, I created a simple directive that loops inside the directive and creates an element with a new isolated scope and adds it to the Pseudo element inside the observer.

Markup

<body ng-controller="main">
   <a ng-click="next()" href="#">Next</a>
   <h1>{{index}}</h1>
   <new-array values='values'></new-array>
</body>

      

Directive



myApp.directive("newArray", function ($compile) {
  return {
    link : function (scope, element, attrs) {
      var getTemplate = function (value, index) {
        var newScope = scope.$new(true);
        newScope.value = value;
        switch(index) {
          case 0 :
            newScope.index = index;
            return  $compile('<div ng-click="$parent.update(value)">I am here {{value.num}} {{value.name}}</div>')(newScope)
            break;
            case 1 :
            return $compile($('<div />', {
              class:'blue',
              html : "<h1>testing{{index}} {{value.name}}</h1>",
              click : function () {
                scope.update({num: scope.values[index].num});
              }
            }))(newScope);
            break;
            case 2 :
            return $compile($('<div />', {
              class:'green',
              html : "<h1>testing{{index}} {{value.name}}</h1>",
              click : function () {
                scope.update({num: scope.values[index].num});
              }
            }))(newScope);
            break;
        }
      }
      scope.$watch('values', function(newVal){
        var html = '', dom = $('<div/>');
        element.empty();
        for(var i=0;i < newVal.length; i++){
          element.append(getTemplate(newVal[i], i))
        }
        //element.replaceWith(dom)
      }, true);
    }
  }
})

      

Worker Plunkr

Note

You really can't think of $ destroy in your case. This is the one destructor

that was used to clean up the events.

+1


source







All Articles