Angular: использование transclude с ng-bind-html

У меня есть следующая настройка angular:

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>'
  };
});

Он извлекает необработанную html-разметку через ajax в контроллере и сохраняет ее в @scope.html. В директиве этот html вставляется в DOM через ng-bind-html.

html (jade) выглядит следующим образом:

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

Это в основном работает. Но внутри этого html, который включен, у меня есть трансклюзивное содержимое, например {{searchType}}, которое я хочу разрешить. К сожалению, это не так, в браузере отображается "{{searchType}}". Что я могу изменить, чтобы трансклюзия работала?

Я читал о $compile и $transclude, но не знаю, как их использовать и поможет ли это решить мою проблему. спасибо!


person Hinrich    schedule 08.12.2014    source источник
comment
$interpolate html, прежде чем установить его в $scope.html в контроллере. См. ответ на этот вопрос: stackoverflow .com/questions/20796102/   -  person Patrick    schedule 08.12.2014
comment
отлично, $interpolate делает свое дело! спасибо!   -  person Hinrich    schedule 08.12.2014


Ответы (1)


с помощью Патрика я смог решить эту проблему. я изменил свой контроллер на

 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(); 
  }]);

и теперь мой html интерполируется на основе переданной области. спасибо!

изменить: $interpolate предназначен только для рендеринга DOM и его анализа в пределах области видимости. он просто возвращает обычный html. если вам действительно нужно получить полный рабочий HTML-шаблон с угловым кодом, используйте $compile. я нашел этот ответ чрезвычайно полезным в устранении различий между $interpolate, $compile и $parse.

person Hinrich    schedule 08.12.2014