在元素内插入一个有角度的 js 模板字符串 [英] Insert an angular js template string inside an element

查看:24
本文介绍了在元素内插入一个有角度的 js 模板字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将一些有角度的 js 模板字符串放入一个元素中,并期望得到一个编译输出.但这并没有发生.

HTML

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

控制器:

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

输出只是{{each}}.

那么如何在元素中插入一个有角度的 js 模板字符串(这里是 $scope.fruitsView)?

我为此做了一个fiddle.

解决方案

在这种情况下,您不想只是插入 HTML",而是要编译它.您可以使用 $compile 服务创建 DOM 节点.

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

如您所见,$compile 返回一个函数,该函数将作用域对象作为参数,根据该作用域对象评估代码.例如,可以使用 element.append() 将结果内容插入到 DOM 中.

重要说明:但在任何情况下都不会有任何与 DOM 相关的代码属于您的控制器.正确的位置是总是一个指令.这段代码很容易被放入指令中,但我想知道你为什么要以编程方式插入 HTML.

你能在这里说明一下,以便我提供更具体的答案吗?

更新

假设您的数据来自一项服务:

.factory( 'myDataService', function () {返回函数(){//显然是 $httpreturn [ "苹果", "香蕉", "橙色" ];};});

你的模板来自一个服务

.factory( 'myTplService', function () {返回函数(){//显然是 $httpreturn '<div><p ng-repeat="item in items">{{item}}</p></div>';};});

然后创建一个简单的指令,读取提供的模板,编译它,并将其添加到显示中:

.directive( 'showData', function ( $compile ) {返回 {范围:真实,链接:函数(范围、元素、属性){变种;attrs.$observe('模板',函数(tpl){如果(angular.isDefined(tpl)){//根据当前作用域编译提供的模板el = $compile( tpl )( scope );//清空元素的愚蠢方式element.html("");//添加模板内容element.append(el);}});}};});

那么从你的角度来看:

<button ng-click="showContent()">显示内容</button><div show-data template="{{template}}"></div>

在控制器中,您只需将其绑定在一起:

.controller( 'MyCtrl', function ( $scope, myDataService, myTplService ) {$scope.showContent = 函数 () {$scope.items = myDataService();//<- 应该更好地传达给指令$scope.template = myTplService();};});

它们应该一起工作!

PS:这一切都假设您的模板来自服务器.如果没有,那么您的模板应该在指令中,这样可以简化事情.

Im trying to put some angular js template string inside an element, and expect an complied output. But that's not happening.

HTML

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

Controller:

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

The ouput is just {{each}}.

So how do i insert an angular js template string (here $scope.fruitsView) inside an element?

I have made a fiddle for this.

解决方案

In this case, you don't want to just "insert HTML", but compile it. You can create DOM nodes using the $compile service.

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

As you can see, $compile returns a function that takes a scope object as a parameter, against which the code is evaluated. The resultant content can be inserted into the DOM with element.append(), for example.

Important note: But under no circumstances does any DOM-related code belong in your controller. The proper place is always a directive. This code can easily be thrown into a directive, but I wonder why you are programmatically inserting the HTML at all.

Can you shed some light here so I can provide a more specific answer?

Update

Assuming your data comes from a service:

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

And your template comes from a service

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

Then you create a simple directive that reads in the provided template, compiles it, and adds it to the display:

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

Then from your view:

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

And in the controller, you simply tie it together:

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

And it should all work together!

PS: this is all assuming your template comes from the server. If it doesn't, then your template should be in the directive, which simplifies things.

这篇关于在元素内插入一个有角度的 js 模板字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆