Angular ng-bind-html 和其中的指令
Posted
技术标签:
【中文标题】Angular ng-bind-html 和其中的指令【英文标题】:angular ng-bind-html and directive within it 【发布时间】:2013-06-29 08:23:24 【问题描述】:Plunker Link
我有一个想要绑定 html 的元素。
<div ng-bind-html="details" upper></div>
这行得通。现在,连同它,我还有一个绑定到绑定 html 的指令:
$scope.details = 'Success! <a href="#/details/12" upper>details</a>'
但是带有 div 和锚点的指令 upper
不计算。如何让它发挥作用?
【问题讨论】:
看我的答案***.com/questions/17343696/… @Chandermani 没有完全使用 ng-bind-html-unsafe 中的指令,而是使用了过滤器。但它会做,我只是创建了一个过滤器并传递给指令。谢谢! @SamSerious 你能说明你是如何为过滤器做的吗? 以上解决方案不处理值的多次变化更好的解决方案***.com/a/25516311/3343425 【参考方案1】:添加这条指令angular-bind-html-compile
.directive('bindHtmlCompile', ['$compile', function ($compile)
return
restrict: 'A',
link: function (scope, element, attrs)
scope.$watch(function ()
return scope.$eval(attrs.bindHtmlCompile);
, function (value)
// Incase value is a TrustedValueHolderType, sometimes it
// needs to be explicitly called into a string in order to
// get the HTML string.
element.html(value && value.toString());
// If scope is provided use it, otherwise use parent scope
var compileScope = scope;
if (attrs.bindHtmlScope)
compileScope = scope.$eval(attrs.bindHtmlScope);
$compile(element.contents())(compileScope);
);
;
]);
像这样使用它:
<div bind-html-compile="data.content"></div>
真的很简单:)
【讨论】:
小心,如果你传递这样的东西: "$scope.loadContent = function() return $sce.trustAsHtml(require('html/main-content.html')); ; "对它你可以获得无限的摘要循环。没有 trustAsHtml 它可以工作。【参考方案2】:对于任何处理已经通过$sce.trustAsHtml
运行的内容的人来说,这是我必须做的不同
function(scope, element, attrs)
var ensureCompileRunsOnce = scope.$watch(function(scope)
return $sce.parseAsHtml(attrs.compile)(scope);
,
function(value)
// when the parsed expression changes assign it into the current DOM
element.html(value);
// compile the new DOM and link it to the current scope.
$compile(element.contents())(scope);
// Use un-watch feature to ensure compilation happens only once.
ensureCompileRunsOnce();
);
这只是指令的link
部分,因为我使用的是不同的布局。您将需要注入$sce
服务以及$compile
。
【讨论】:
【参考方案3】:我也遇到了这个问题,在互联网上搜索了几个小时后,我阅读了@Chandermani 的评论,这被证明是解决方案。 您需要使用此模式调用“编译”指令:
HTML:
<div compile="details"></div>
JS:
.directive('compile', ['$compile', function ($compile)
return function(scope, element, attrs)
scope.$watch(
function(scope)
// watch the 'compile' expression for changes
return scope.$eval(attrs.compile);
,
function(value)
// when the 'compile' expression changes
// assign it into the current DOM
element.html(value);
// compile the new DOM and link it to the current
// scope.
// NOTE: we only compile .childNodes so that
// we don't get into infinite loop compiling ourselves
$compile(element.contents())(scope);
);
;
])
你可以看到一个工作的fiddle of it here
【讨论】:
在第 2 行,即。function(scope, element, attrs)
,你从这三个参数中哪里得到的,scope、element 和 attrs?
@spaffy - 它们是 Angular 框架对 link
属性的签名的一部分。每当 Angular 框架调用 link
时,它们都会自动传递。它们将始终可用。
干得好。你为我节省了同样的搜索时间。我正在从 SharePoint 视图 REST API 中提取内容,该 API 本身包含 Angular 标记,例如 ng-repeat。您的指示使一切正常。谢谢!
感谢您的指示,它解决了我遇到的问题。现在角度代码被编译但太多次了。具有 3 个对象的 ng-repeat 变成相同的值,每个值只有 3 倍。这里出了什么问题?
如果您一直在使用来自另一个函数的$sce.trustAsHtml
创建将使用此指令“编译”的 HTML,您应该删除它。感谢@apopxy【参考方案4】:
很遗憾,我没有足够的声誉来发表评论。
我无法让它工作很长时间。我修改了我的 ng-bind-html
代码以使用此自定义指令,但我未能删除 ng-bind-html 工作所需的 $scope.html = $sce.trustAsHtml($scope.html)
。一旦我删除它,编译功能就开始工作了。
【讨论】:
【参考方案5】:我发现的最佳解决方案!我复制了它,它完全符合我的需要。谢谢,谢谢,谢谢...
在指令链接函数中我有
app.directive('element',function($compile)
.
.
var addXml = function()
var el = $compile('<xml-definitions definitions="definitions" />')($scope);
$scope.renderingElement = el.html();
.
.
在指令模板中:
<span compile="renderingElement"></span>
【讨论】:
【参考方案6】:感谢 vkammerer 的出色回答。我建议的一项优化是在编译运行一次后不观看。 watch 表达式中的 $eval 可能会对性能产生影响。
angular.module('vkApp')
.directive('compile', ['$compile', function ($compile)
return function(scope, element, attrs)
var ensureCompileRunsOnce = scope.$watch(
function(scope)
// watch the 'compile' expression for changes
return scope.$eval(attrs.compile);
,
function(value)
// when the 'compile' expression changes
// assign it into the current DOM
element.html(value);
// compile the new DOM and link it to the current
// scope.
// NOTE: we only compile .childNodes so that
// we don't get into infinite loop compiling ourselves
$compile(element.contents())(scope);
// Use un-watch feature to ensure compilation happens only once.
ensureCompileRunsOnce();
);
;
]);
Here's a forked and updated fiddle.
【讨论】:
我可以反过来吗? 这不是响应 ajax 的工作,而是接受的答案工作 警告:此答案的小提琴有效,但答案中发布的代码中的.directive()
代码无效。
这个对我有用。选择的答案将触发“错误:$rootScope:infdig Infinite $digest Loop”
您不需要显式的$eval
- 您可以直接使用attrs.compile
代替被监视的匿名函数。如果你只提供一个字符串表达式,Angular 无论如何都会调用$eval
。以上是关于Angular ng-bind-html 和其中的指令的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 ng-bind-html 插入 Angular 1.5 组件
使用 ng-bind-html 来自 Angular Array 的 iframe 视频
angularjs 可以加入html标签方法------ng-bind-html的用法总结