在元素内插入一个有角度的 js 模板字符串 [英] Insert an angular js template string inside an element
问题描述
我试图将一些有角度的 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屋!