动态选项卡中的动态内容(Angular、UI Bootstrap) [英] Dynamic Content in Dynamic Tab (Angular, UI Bootstrap)
问题描述
我想在使用 AngularJs 和 UI Bootstrap 动态生成的选项卡的内容中使用 ng-include.
我这里有一个Plunker:http://plnkr.co/edit/2mpbovsu2eDrUdu8t7SM?p=preview
<uib-tabset><uib-tab ng-repeat="tab in tabs" active="tab.active" disable="tab.disabled"><uib-tab-heading>{{tab.title}} <i class="glyphicon glyphicon-remove-sign" ng-click="removeTab($index)"></i></uib-tab-heading>{{tab.content}}</uib-tab></uib-tabset>
JS代码:
$scope.addTab = function() {var len = $scope.tabs.length + 1;var numLbl = '' + ((len > 9) ? '' : '0') + String(len);var mrkUp = ''+'<h1>新标签' + numLbl + ' {{foo}}</h1>'+'<div ng-include="tab.tabUrl" class="ng-scope"></div>'+'</div>';$scope.tabs.push({title: 'Tab ' + numLbl, content: $compile(angular.element(mrkUp))($scope)});}在Plunker 中,单击添加选项卡"按钮.它调用 $scope 中的一个函数,该函数将一个新选项卡推送到集合,但传入一些包含 ng-include 指令的动态生成的内容.预期的输出是 ng-include 将显示在选项卡内容区域内.
谢谢
解决方案 在您的 Plunker 中,您使用的是 ng-bind-html
,它不会为您编译 HTML.您可以创建一个为您执行此操作的新指令.
ng-bind-html
的源代码:
var ngBindHtmlDirective = ['$sce', '$parse', '$compile', function($sce, $parse, $compile) {返回 {限制:'A',编译:函数 ngBindHtmlCompile(tElement, tAttrs) {var ngBindHtmlGetter = $parse(tAttrs.ngBindHtml);var ngBindHtmlWatch = $parse(tAttrs.ngBindHtml, function getStringValue(value) {return (value || '').toString();});$compile.$$addBindingClass(tElement);返回函数 ngBindHtmlLink(scope, element, attr) {$compile.$$addBindingInfo(element, attr.ngBindHtml);scope.$watch(ngBindHtmlWatch, 函数 ngBindHtmlWatchAction() {//我们重新评估 expr 因为我们想要 TrustedValueHolderType//对于 $sce,不是字符串element.html($sce.getTrustedHtml(ngBindHtmlGetter(scope)) || '');});};}};}];
为新指令选择一个名称,例如 compile-html
.
将 tAttrs.ngBindHtml
替换为 tAttrs.compileHtml
(或您选择的任何名称).
您需要将 $sce.getTrustedHtml
替换为 $sce.trustAsHtml
,否则您将收到 Error: [$sce:unsafe] Attempting to use an安全上下文中的不安全值.
然后需要调用$compile
:
$compile(element.contents())(scope);
完整指令:
app.directive('compileHtml', ['$sce', '$parse', '$compile',函数($sce,$parse,$compile){返回 {限制:'A',编译:函数 ngBindHtmlCompile(tElement, tAttrs) {var ngBindHtmlGetter = $parse(tAttrs.compileHtml);var ngBindHtmlWatch = $parse(tAttrs.compileHtml, function getStringValue(value) {return (value || '').toString();});$compile.$$addBindingClass(tElement);返回函数 ngBindHtmlLink(scope, element, attr) {$compile.$$addBindingInfo(element, attr.compileHtml);scope.$watch(ngBindHtmlWatch, 函数 ngBindHtmlWatchAction() {element.html($sce.trustAsHtml(ngBindHtmlGetter(scope)) || '');$compile(element.contents())(scope);});};}};}]);
用法:
<div compile-html="tab.content"></div>
演示: http://plnkr.co/edit/TRYAaxeEPMTAay6rqEXp?p=预览
I'd like to use ng-include in the content of a dynamically generated tab using AngularJs and UI Bootstrap.
I have a Plunker here:
http://plnkr.co/edit/2mpbovsu2eDrUdu8t7SM?p=preview
<div id="mainCntr" style="padding: 20px;">
<uib-tabset>
<uib-tab ng-repeat="tab in tabs" active="tab.active" disable="tab.disabled">
<uib-tab-heading>
{{tab.title}} <i class="glyphicon glyphicon-remove-sign" ng-click="removeTab($index)"></i>
</uib-tab-heading>
{{tab.content}}
</uib-tab>
</uib-tabset>
</div>
JS Code:
$scope.addTab = function() {
var len = $scope.tabs.length + 1;
var numLbl = '' + ((len > 9) ? '' : '0') + String(len);
var mrkUp = '<div>' +
'<h1>New Tab ' + numLbl + ' {{foo}}</h1>' +
'<div ng-include="tab.tabUrl" class="ng-scope"></div>' +
'</div>';
$scope.tabs.push({title: 'Tab ' + numLbl, content: $compile(angular.element(mrkUp))($scope)});
}
In the Plunker, click the "Add Tab" button. It calls a function in $scope that pushes a new tab to the collection but passing in some dynamically generated content that includes a ng-include directive. The expected output is that the ng-include will be displayed inside of the tab content area.
Thanks
解决方案 In your Plunker you are using ng-bind-html
which doesn't compile the HTML for you. You can create a new directive that does that for you.
Source code for ng-bind-html
:
var ngBindHtmlDirective = ['$sce', '$parse', '$compile', function($sce, $parse, $compile) {
return {
restrict: 'A',
compile: function ngBindHtmlCompile(tElement, tAttrs) {
var ngBindHtmlGetter = $parse(tAttrs.ngBindHtml);
var ngBindHtmlWatch = $parse(tAttrs.ngBindHtml, function getStringValue(value) {
return (value || '').toString();
});
$compile.$$addBindingClass(tElement);
return function ngBindHtmlLink(scope, element, attr) {
$compile.$$addBindingInfo(element, attr.ngBindHtml);
scope.$watch(ngBindHtmlWatch, function ngBindHtmlWatchAction() {
// we re-evaluate the expr because we want a TrustedValueHolderType
// for $sce, not a string
element.html($sce.getTrustedHtml(ngBindHtmlGetter(scope)) || '');
});
};
}
};
}];
Pick a name for the new directive, for example compile-html
.
Replace tAttrs.ngBindHtml
with tAttrs.compileHtml
(or whatever name you picked).
You need to replace $sce.getTrustedHtml
with $sce.trustAsHtml
, or you will get Error: [$sce:unsafe] Attempting to use an unsafe value in a safe context.
Then you need to call $compile
:
$compile(element.contents())(scope);
Full directive:
app.directive('compileHtml', ['$sce', '$parse', '$compile',
function($sce, $parse, $compile) {
return {
restrict: 'A',
compile: function ngBindHtmlCompile(tElement, tAttrs) {
var ngBindHtmlGetter = $parse(tAttrs.compileHtml);
var ngBindHtmlWatch = $parse(tAttrs.compileHtml, function getStringValue(value) {
return (value || '').toString();
});
$compile.$$addBindingClass(tElement);
return function ngBindHtmlLink(scope, element, attr) {
$compile.$$addBindingInfo(element, attr.compileHtml);
scope.$watch(ngBindHtmlWatch, function ngBindHtmlWatchAction() {
element.html($sce.trustAsHtml(ngBindHtmlGetter(scope)) || '');
$compile(element.contents())(scope);
});
};
}
};
}
]);
Usage:
<div compile-html="tab.content"></div>
Demo: http://plnkr.co/edit/TRYAaxeEPMTAay6rqEXp?p=preview
这篇关于动态选项卡中的动态内容(Angular、UI Bootstrap)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文