Search code examples
javascriptangularjsangularjs-directivetransclusionng-bind-html

Angular: using transclude with ng-bind-html


I have the following angular setup:

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

app.filter('unsafe', function($sce) {
  return $sce.trustAsHtml;
});

app.controller('SearchController', ['$scope', '$http', function($scope, $http) {
  $scope.searchString = '';
  $scope.searchType = 'Artist';
  $scope.updateHtml = function() {
    $http.get('/search', {
      params: {
        searchString: $scope.searchString,
        searchType: $scope.searchType
      }
    }).success(function(data) {
      $scope.html = data;
    }).error(function(err){
      $scope.html = err;
    });
  };
  $scope.updateHtml(); 
}]);

app.directive('searchDirective', function() {
  return {
    restrict: 'A',
    transclude: true,
    template: '<div ng-bind-html="html | unsafe" ng-transclude></div>'
  };
});

It pulls raw html markup through ajax in the controller and stores it in @scope.html. In the directive, this html is inserted into the DOM through ng-bind-html.

The html (jade) looks as follows:

#search(ng-controller="SearchController" search-directive)

It basically works. But inside this html that is included, i have some transclusive content, like {{searchType}} that i want to be resolved. Unfortunatly, that is not the case, it shows "{{searchType}}" in the browser. What can i change to make the transclusion work?

I read about $compile and $transclude, but i don't know how to use it or if it can help me solve my issue. thx!


Solution

  • with the help of Patrick, i was able to solve it. i changed my controller to

     app.controller('SearchController', ['$scope', '$http', '$interpolate',  
                  function($scope, $http, $interpolate) {
        $scope.searchString = '';
        $scope.searchType = 'Artist';
        $scope.updateHtml = function() {
          $http.get('/search', {
            params: {
              searchString: $scope.searchString,
              searchType: $scope.searchType
            }
          }).success(function(data) {
            $scope.html = $interpolate(data)($scope); // <<-- difference here
          }).error(function(err){
            $scope.html = err;
          });
        };
        $scope.updateHtml(); 
      }]);
    

    and now my html is interpolated based on the passed-in scope. thank you!

    edit: $interpolate is only for rendering the DOM and parsing it through the scope. it simply returns plain html. if you need to actually retrieve a full working html template, with angular code in it, use $compile. i found this answer extremely helpful in sorting out the differences between $interpolate, $compile and $parse.