1

I'm attempting to build dynamic HTML strings which include a directive that reacts to changes in a scope variable. If I build the strings statically then my $watch works properly, but if the strings are dynamic then the $watch never fires.

I am sure the answer lies somewhere in use of $compile, and I have studied numerous examples, but I can't seem to make them work for my specific needs.

Is this possible?

My plunkr, which demonstrates referencing sentences with a superscript tag.

index.html

<body ng-controller="MainCtrl">
    <h3>Static Example</h3>
    <div>Humpty Dumpty sat<ref><sup>1</sup></ref> on a wall.</div>
    <div>Humpty Dumpty had a great<ref><sup>2</sup></ref> fall.</div>

    <h3>Dynamic Example</h3>
    <div ng-repeat="item in dynamic">
      <span ng-bind-html="item | to_trusted"></span>
    </div>
    <br>
    <input type="checkbox" ng-click="sup = !sup"> hide/show
</body>

app.js

var app = angular.module('app', [])
  .filter('to_trusted', ['$sce', function($sce) {
    return function(text) {
      return $sce.trustAsHtml(text);
    };
}]);

app.controller('MainCtrl', function($scope) {
  $scope.sup = true;
  $scope.dynamic = ["Humpty Dumpty sat on a wall.<ref><sup>1</sup></ref>", 
                    "Humpty Dumpty had a great fall.<ref><sup>2</sup></ref>"];
});

app.directive('sup', function($compile) {
  return {
    restrict: 'E',
    link: function(scope, element) {
      scope.$watch('sup', function() {
        element.css({ display: scope.sup ? 'inline' : 'none' });
      });
    }
}});
5

1 Answer 1

1

You have to change your directive like below.

app.directive('compile', ['$compile', function ($compile) {
    return function (scope, element, attrs) {
        scope.$watch(
      function (scope) {
          return scope.$eval(attrs.compile);
      },
      function (value) {
          element.html(value);
          $compile(element.contents())(scope);
      }
    );
    };
}]);

then use it in html like this.

<h3>Dynamic Example</h3>
<div ng-repeat="item in dynamic">
  <span compile="item"></span>
</div>

Demo code

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.