1

I am trying to add a a-tag with a filter to an html-content. I'm binding the html-content with ng-bind-html and the a-tag contains ng-click. But my problem is, ng-click is not working.

I am doing this in the html file

<div ng-bind-html="text | addLink"></div>

my filter looks like this

app.filter('addLink', ['$sce', function($sce) {
  return function(text) {
    text += '';
    text += '<a class="btn btn-link" ng-click="readMore()">readMore</a>'
    text = $sce.trustAsHtml(text);
    return text;
  }
}]);

and this is my controller

app.controller('MainCtrl', ['$scope', '$sce', function($scope, $sce) {

  var text = '<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium.</p>' +
            '<p>Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,</p>'

  $scope.text = $sce.trustAsHtml(text);
  $scope.readMoreIsCalled = 'read more was not called yet';

  $scope.readMore = function() {
    console.log("READ MORE");
    $scope.readMoreIsCalled = 'Read more method was called';
  }

}]);

I created a Plunk

Can anybody help me?

Thanks!

4
  • This is a common problem. This happens when your bind html but you dont compile it ( it doesn't go through and read all the directives in your html) . I've seen people use a custom compile directive to fix this. There are other answers out there just google around. reddit.com/r/angularjs/comments/312mbg/… Commented Feb 9, 2016 at 14:26
  • Instead of using a filter. I would recommend using a directive with a $compile . Check this example : stackoverflow.com/questions/22737927/… Commented Feb 9, 2016 at 14:36
  • @Nix and aayush shrestha Thank you very much. I tried your solutions and it's working now. Commented Feb 9, 2016 at 14:47
  • @stefOCDP I'd second the use of a directive in this situation, here's an example of how you can use a directive in your plnkr: plnkr.co/edit/MyXTiuBAI9AXDMlN3Dr9?p=preview Commented Feb 9, 2016 at 14:51

1 Answer 1

1

I could find the solution with the help from the comments. I just had to create a new directive, to compile the inserted html content. Here is my code

index.html

<div compile="text | addLink"></div>

filter

app.filter('addLink', [function() {
  return function(text) {
    text += '';
    text += '<a class="btn btn-link" ng-click="readMore()">readMore</a>'
    return text;
  }
}]);

the new directive

app.directive('compile', ['$compile', function ($compile) {
  return function(scope, element, attrs) {
    scope.$watch(
      function(scope) {
        // watch the 'compile' expression for changes
        return scope.$eval(attrs.compile);
      },
      function(value) {
        // when the 'compile' expression changes
        // assign it into the current DOM
        element.html(value);

        // compile the new DOM and link it to the current
        // scope.
        // NOTE: we only compile .childNodes so that
        // we don't get into infinite loop compiling ourselves
        $compile(element.contents())(scope);
      }
  );
};
}]);

the controller

app.controller('MainCtrl', ['$scope', function($scope) {
  var text = '<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium.</p>' +
            '<p>Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,</p>'

  $scope.text = text;
  $scope.readMoreIsCalled = 'read more was not called yet';

  $scope.readMore = function() {
    console.log("READ MORE");
    $scope.readMoreIsCalled = 'Read more method was called';
  }

}]);

This is the working Plunk

But notice, now it's not necessary anymore to use

$scp.trustAsHtml()
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.