在元素内插入角度js模板字符串

时间:2013-02-13 05:17:29

标签: angularjs

我试图将一些角度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}}

那么如何在元素中插入角度js模板字符串(此处为$scope.fruitsView)?

我为此做了fiddle

1 个答案:

答案 0 :(得分:95)

在这种情况下,您不希望只是“插入HTML”,而是编译它。您可以使用$compile服务创建DOM节点。

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

如您所见,$compile返回一个函数,该函数将范围对象作为参数,对其进行评估。例如,可以使用element.append()将结果内容插入到DOM中。

重要提示:但在情况下,任何与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:这都是假设您的模板来自服务器。如果没有,那么你的模板应该在指令中,这简化了事情。