让ng-repeat在AngularJS的$ interpolate服务中工作 [英] Getting ng-repeat to work inside of AngularJS's $interpolate service
问题描述
我正在使用Bootstrap的AngularJs-UI组件。我想将填充的模板插入到popover功能的一个数据元素中。这适用于所有不在ng-repeat内部的元素。如何让ng-repeat元素在插值模板中工作?
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?
我有一个 http://plnkr.co/edit/Cuku7qaUTL1lxRkafKzv 它无法正常工作,因为我不知道如何在plunker中获取Angular-UI-bootstrap。
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>
我的本地范围具有函数 createHTML()
看起来像这样。
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);
}
});
服务是
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
}
});
模板:
<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
不处理 ngRepeat
等指令(
解析,插值和编译之间的差异)。 $ interpolate
:
$interpolate
doesn't handle directives like ngRepeat
(
Difference between parse, interpolate and compile ). $interpolate
:
将带有标记的字符串编译为插值函数。这个
服务由HTML $编译服务用于数据绑定。
Compiles a string with markup into an interpolation function. This service is used by the HTML $compile service for data binding.
处理 ngRepeat
以及您想要的其他指令 $ compile
。但是对于你的用例 $ compile
将会导致很多变化,因为:
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:
-
它需要一个范围来编译,而不仅仅是像
$ interpolate
这样的上下文。此外,它需要thingy
的范围。
It needs a scope to compile against rather than just a context like
$interpolate
. Moreover it needs the scopethingy
is on.
这意味着我们需要引用您的属性,如此{ {thingy.blah}}而不是模板中的{{blah}}。
This means we'll need to reference your properties like so {{thingy.blah}} instead of {{blah}} inside your template.
当弹出窗口在dom上时,需要进行编译。
The compile needs to happen when the popup is on the dom.
所以我们可以只需在服务中用 $ compile
替换 $ interpolate
。
So we can't just replace $interpolate
with $compile
inside your service.
一种方法是用以下指令替换 data-ng-bind-html
,该指令的作用类似于 ng-bind-html
有一个内置的 $ compile
(显然你应该只使用你认为安全的html )。
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);
}
);
};
});
像这样使用(使用编译
替换 ng-bind-html
:
Used like so (with compile
replacing ng-bind-html
:
<div class="popover-content" compile="content"></div>
一个问题是我们需要 thingy
属于范围。有几种方法可以处理 - 但为了演示目的,我已经手动返回到调用popover的范围 - 这是2范围因此范围。$ parent。$ parent
。
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
.
使用此编译指令不再 $ interpolate
或 $ sanitize
因此服务中的函数可以缩小到只返回相应的模板:
Using this compile directive you no longer $interpolate
or $sanitize
so 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;
}
这篇关于让ng-repeat在AngularJS的$ interpolate服务中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!