Подтвердить что ты не робот

Вставьте строку шаблона angular js внутри элемента

Я пытаюсь поместить в элемент некоторую строку шаблона angular js внутри элемента и ожидать результат с соблюдением. Но этого не происходит.

HTML

<div ng-controller="testController">
    <div ng-bind-html-unsafe="fruitsView"></div>
</div>

Контроллер:

function filterController($scope){
    ...
    $scope.arr = ["APPLE", "BANANA"];
    $scope.fruitsView = '<div><p ng-repeat="each in arr">{{each}}</p></div>';
}

Вывод только {{each}}.

Итак, как мне вставить строку шаблона angular js (здесь $scope.fruitsView) внутри элемента?

Я сделал fiddle для этого.

4b9b3361

Ответ 1

В этом случае вы не хотите просто "вставлять HTML", а компилируете его. Вы можете создавать узлы DOM с помощью службы $compile.

var tpl = $compile( '<div><p ng-repeat="each in arr">{{each}}</p></div>' )( scope );

Как вы можете видеть, $compile возвращает функцию, которая принимает объект scope как параметр, по которому вычисляется код. Результирующий контент можно вставить в DOM с помощью element.append(), например.

Важное примечание. Но ни при каких обстоятельствах какой-либо код, связанный с DOM, не входит в ваш контроллер. Правильное место всегда является директивой. Этот код можно легко ввести в директиву, но мне интересно, почему вы программно вставляете HTML вообще.

Можете ли вы пролить свет здесь, чтобы я мог предоставить более конкретный ответ?

Обновление

Предполагая, что ваши данные поступают из службы:

.factory( 'myDataService', function () {
  return function () {
    // obviously would be $http
    return [ "Apple", "Banana", "Orange" ];
  };
});

И ваш шаблон поступает из службы

.factory( 'myTplService', function () {
  return function () {
    // obviously would be $http
    return '<div><p ng-repeat="item in items">{{item}}</p></div>';
  };
});

Затем вы создаете простую директиву, которая читает в предоставленном шаблоне, компилирует его и добавляет на экран:

.directive( 'showData', function ( $compile ) {
  return {
    scope: true,
    link: function ( scope, element, attrs ) {
      var el;

      attrs.$observe( 'template', function ( tpl ) {
        if ( angular.isDefined( tpl ) ) {
          // compile the provided template against the current scope
          el = $compile( tpl )( scope );

          // stupid way of emptying the element
          element.html("");

          // add the template content
          element.append( el );
        }
      });
    }
  };
});

Затем с вашего вида:

<div ng-controller="MyCtrl">
   <button ng-click="showContent()">Show the Content</button>
   <div show-data template="{{template}}"></div>
</div>

И в контроллере вы просто связываете это:

.controller( 'MyCtrl', function ( $scope, myDataService, myTplService ) {
  $scope.showContent = function () {
    $scope.items = myDataService(); // <- should be communicated to directive better
    $scope.template = myTplService();
  };
});

И все должно работать вместе!

PS: все это предполагает, что ваш шаблон поступает с сервера. Если это не так, то ваш шаблон должен быть в директиве, что упрощает вещи.