歌厅NG重复到AngularJS中的$插值服务内工作 [英] Geting ng-repeat to work inside of AngularJS's $interpolate service

查看:144
本文介绍了歌厅NG重复到AngularJS中的$插值服务内工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的引导AngularJs UI组件。我想插入填写模板到了酥料饼功能的数据元素之一。这工作找不NG重复内的所有元素。我如何获得了NG-重复元素添加到模板插值里面工作?

我在 http://plnkr.co/edit/Cuku7qaUTL1lxRkafKzv 它不工作,因为我不知道plunker如何让角-UI-引导到plunker。

 < D​​IV数据酥料饼={{createHTML()}}>有些内容与LT; / DIV>

我的本地范围具有的功能 createHTML(),看起来是这样的。

  angular.module('对myApp',['ngSanitize'])
  .controller(myController的功能(为myService){
    $ scope.createHTML =功能(){
      VAR啄= {胡说:foobar的,收藏:[1,2,3]};
      返回myService.html_for(啄);
    }
  });

和服务是

  angular.module('对myApp')
  。服务('为myService',函数($ templateCache,$插值,$ sanitize方法,$日志){
    使用严格的;    功能html_for(啄){
      变种模板= $ templateCache.get('thingyTemplate.html'),
        链接= $插值(模板)
        HTML链接=(啄)
        不安全= $的sanitize(HTML);
      返回不安全;
    }    返回{
      html_for:html_for
    }
  });

模板:

 <脚本类型=文/ NG-模板ID =thingyTemplate.html>
  < D​​IV>
    < D​​IV><强>胡说:LT; / STRONG> {{嗒嗒}}< / DIV>
    < D​​IV数据-NG-重复=富在收集><强>集合:LT; / STRONG> {{富}}< / DIV>
    < D​​IV><强>收缴[0]:其中; / STRONG> {{集合[0]}}< / DIV>
    < D​​IV><强>收缴[1]:其中; / STRONG> {{集合[1]}}< / DIV>
    < D​​IV><强>收缴[2]:其中; / STRONG> {{集合[2]}}< / DIV>
  < / DIV>
< / SCRIPT><脚本类型=文/ NG-模板ID =模板/酥料饼/ popover.html>
< D​​IV CLASS =酥料饼{{位置}}数据-NG-CLASS ={在:isOpen会(),褪色:动画()}>
  < D​​IV CLASS =箭头>< / DIV>  < D​​IV CLASS =酥料饼-内>
    < H3类=酥料饼的标题数据-NG-绑定=标题数据-NG-秀=标题>< / H3 GT&;
    < D​​IV CLASS =酥料饼的内容的数据-NG绑定-HTML =内容>< / DIV>
  < / DIV>
< / DIV>
< / SCRIPT>


解决方案

$插值不处理如 ngRepeat
<一href=\"http://stackoverflow.com/questions/17900588/what-is-the-difference-between-the-parse-interpolate-and-compile-services\">Difference解析之间,插值和编译)。 $插值


  

与编译标记中的字符串转换为插补功能。这个
  服务所使用的HTML $编译服务用于数据绑定。


要处理 ngRepeat 等指令你想 $编译 。但是,对于您的使用情况 $编译将要造成的,不幸的是,在众多的变化,因为:


  • 这需要一个范围进行编译,而不是就像 $插值的上下文。此外,它需要范围

    这意味着我们需要引用像这样{{thingy.blah}},而不是你的属性{{等等}}您的模板中。


  • 编译时需要在弹出的是对DOM发生。


  • 弹出仅在DOM时,它是开放的。

因此​​,我们不能仅仅替换 $插值 $编译服务里。

一种方法是使用下面的指令,就像一个来代替数据-NG绑定-HTML NG-绑定-HTML 的有一个内置的 $编译(显然你应该只使用你知道是安全的HTML用这个)。

  .directive('编译',函数($编译){
  返回功能(范围,元素,ATTRS){
    范围。$手表(
      功能(适用范围){
        返回范围$的eval(attrs.compile)。
      },
      功能(值){
        VAR的结果= element.html(值);
        $编译(element.contents())($范围父父$。);
      }
    );
  };
});

使用像这样

(用编译替换 NG-绑定-HTML

 &LT; D​​IV CLASS =酥料饼的内容编=内容&GT;&LT; / DIV&GT;

一个问题是,我们需要来在范围。有几个处理方式但─但出于演示的目的,我走了手动备份到范围酥料饼是由被称为 - 这是2示波器起来从而 $范围父父$ <。 / code>。

使用这个编译指令,你不再 $插值 $消毒所以在你的服务功能可以收缩下来刚刚返回相应的模板:

 函数html_for(){
  变种模板= $ templateCache.get('thingyTemplate.html');
  返回模板;
}

<大骨节病> 演示小提琴

I am using the AngularJs-UI components for Bootstrap. I would like to insert a filled out template into one of the data elements for the popover feature. This works find for all elements not inside of a ng-repeat. How do I get the ng-repeat elements to work inside of a interpolated template?

I have a plunker at http://plnkr.co/edit/Cuku7qaUTL1lxRkafKzv Its not working because I don't know how to get Angular-UI-bootstrap to in plunker.

<div data-popover="{{createHTML()}}">some content</div>

My local scope has the function createHTML() that looks something like this.

angular.module('myApp', ['ngSanitize'])
  .controller("myController", function(myService){
    $scope.createHTML = function() {
      var thingy = { blah: "foobar", collection: [ "1", "2", "3" ] };
      return myService.html_for(thingy);
    }
  });

And the service is

angular.module('myApp')
  .service('myService', function($templateCache, $interpolate, $sanitize, $log) {
    "use strict";

    function html_for(thingy) {
      var template = $templateCache.get('thingyTemplate.html'),
        link = $interpolate(template),
        html = link(thingy),
        unsafe = $sanitize(html);
      return unsafe;
    }

    return {
      html_for: html_for
    }
  });

Templates:

<script type="text/ng-template" id="thingyTemplate.html">
  <div>
    <div><strong>Blah:</strong> {{blah}}</div>
    <div data-ng-repeat="foo in collection"><strong>Collection:</strong> {{foo}}</div>
    <div><strong>Collection[0]:</strong> {{collection[0]}}</div>
    <div><strong>Collection[1]:</strong> {{collection[1]}}</div>
    <div><strong>Collection[2]:</strong> {{collection[2]}}</div>
  </div>
</script>

<script type="text/ng-template" id="template/popover/popover.html">
<div class="popover {{placement}}" data-ng-class="{ in: isOpen(), fade: animation() }">
  <div class="arrow"></div>

  <div class="popover-inner">
    <h3 class="popover-title" data-ng-bind="title" data-ng-show="title"></h3>
    <div class="popover-content" data-ng-bind-html="content"></div>
  </div>
</div>
</script>

解决方案

$interpolate doesn't handle directives like ngRepeat ( Difference between parse, interpolate and compile ). $interpolate:

Compiles a string with markup into an interpolation function. This service is used by the HTML $compile service for data binding.

To handle ngRepeat and other directives you want $compile. But for your use case $compile is going to result, unfortunately, in a number of changes because:

  • It needs a scope to compile against rather than just a context like $interpolate. Moreover it needs the scope thingy is on.

    This means we'll need to reference your properties like so {{thingy.blah}} instead of {{blah}} inside your template.

  • The compile needs to happen when the popup is on the dom.

  • The popup is only on the dom when it's open.

So we can't just replace $interpolate with $compile inside your service.

One approach is to replace data-ng-bind-html with the following directive that acts like an ng-bind-html that has a built in $compile (clearly you should only use this with html that you know is safe).

.directive('compile', function($compile) {
  return function(scope, element, attrs) {
    scope.$watch(
      function(scope) {
        return scope.$eval(attrs.compile);
      },
      function(value) {
        var result = element.html(value);
        $compile(element.contents())(scope.$parent.$parent);
      }
    );
  };
});

Used like so (with compile replacing ng-bind-html:

  <div class="popover-content" compile="content"></div>

One issue is that we need thingy to be in scope. There's a few of ways of handling that- but for demonstration purposes I've manually gone back up to the scope the popover is called from - which is 2 scopes up thus the scope.$parent.$parent.

Using this compile directive you no longer $interpolate or $sanitizeso the function in your service can shrink down to just returning the appropriate template:

function html_for() {
  var template = $templateCache.get('thingyTemplate.html');
  return template;
}

demo fiddle

这篇关于歌厅NG重复到AngularJS中的$插值服务内工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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