Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jquery breaks angular directive

I'm relatively new to angular and after hours of debugging i found some incompatibility when adding jquery. The directive works fine without jquery but breaks with it :/

Here is a plnkr:

http://plnkr.co/edit/sRwqrWV1ha4Dp7lvsSAg?p=preview

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

app.directive('dynamic', function ($compile) {
  return {
    restrict: 'A',
    replace: true,
    link: function (scope, ele, attrs) {
      scope.$watch(attrs.dynamic, function(html) {
        ele.html(html);
        $compile(ele.contents())(scope);
      });
    }
  };
})

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

    $scope.trustedHtml = $sce.trustAsHtml('<button ng-click="testAlert()">Submit</button>');  

    $scope.testAlert = function () {
        alert('testing');
    };

});

like image 624
MuschPusch Avatar asked Jan 23 '26 03:01

MuschPusch


1 Answers

The problem comes from the fact that $sce.trustAsHtml does not return HTML string, and jQuery overrides the .html method.

You can fix the issue by:

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

app.directive('dynamic', function ($compile) {
    return {
        restrict: 'A',
        replace: true,
        link: function (scope, ele, attrs) {
            scope.$watch(attrs.dynamic, function (html) {
                ele.html(html.$$unwrapTrustedValue());
                $compile(ele.contents())(scope);
            });
        }
    };
})

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

    $scope.trustedHtml = $sce.trustAsHtml('<button ng-click="testAlert()">Submit</button>');

    $scope.testAlert = function () {
        alert('testing');
    };

});

Plunkr

NOTE: This solves the problem but I don't find using $$unwrapTrustedValue as a good practice. Better solution will be to have a template which binds to attrs.dynamic.

This is a kind of better solution: http://plnkr.co/edit/xjS9gTJfyXvTL4LNzXub?p=preview

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

app.directive('dynamic', function ($compile) {
    return {
        restrict: 'A',
        replace: true,
        template: '<span ng-bind-html="dynamic" ng-click="method()"></span>',
        scope: {
            dynamic: '=',
            method: '&'
        }
    };
})

app.controller('MainCtrl', function ($scope, $sce, $compile) {
    $scope.trustedHtml = $sce.trustAsHtml('<button>Submit</button>');
    $scope.testAlert = function () {
        alert('testing');
    };
});

HTML

<div dynamic="trustedHtml" method="testAlert()"></div>
like image 172
Minko Gechev Avatar answered Jan 25 '26 23:01

Minko Gechev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!