Question

Recently have been trying to build kind of a bulletproof directive for inserting inline svgs. It works pretty fine, but recently I wanted to add some animation triggered when class "animate" is add to the inserted element. Problem is that $watch applies to the old element (the one before replaceWith).

I have been trying anything, but I can not make it work. How to get an access to the element after the replacement?

Here is my code:

angular.module('test')
.directive('svgPng', ['$compile', function ($compile) {
  return {
    link: function(scope,elem,attrs) {
      elem.on('load', function(){
        var ext = function(s){return s.substr(s.length-3);},
          src = attrs.src;
        if (ext(src) === 'svg'){
          if(window.Modernizr && window.Modernizr.svg){
            Snap.load(src, function (svg){
              elem = elem.replaceWith($compile(svg.node)(scope));
              if(attrs.animate === 'true'){
                scope.$watch(function() {return elem.attr('class'); }, function(newValue){
                 //some animation
                }
              }
              console.log(elem); //gives old elem instead of svg.node
            });
          } else {
            if(attrs.fallback){
              elem.attr('src', attrs.fallback);
            } else {
              elem.attr('src', attrs.src.substr(3) + 'png');
            }
          }
        }
      });
    }
  };
}]);
Was it helpful?

Solution

elem isn't getting updated with the newly compiled element because .replaceWith doesn't return the new element. http://api.jquery.com/replacewith/

The .replaceWith() method, like most jQuery methods, returns the jQuery object so that other methods can be chained onto it. However, it must be noted that the original jQuery object is returned. This object refers to the element that has been removed from the DOM, not the new element that has replaced it

You need to store the compiled element and replace with that.

var compiled = $compile(svg.node)(scope);
elem.replaceWith(compiled);
elem = compiled;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top