【发布时间】:2014-04-05 00:30:04
【问题描述】:
我不确定标题是否正确。我正在做的事情有点过头了,因为我对 Angular 还很陌生。
我正在尝试运行一个来自绑定值的指令。该指令返回 HTML。我的问题是试图让该 HTML 显示。我想我错过了 transclude 的概念(因为我没有使用它),我都搞砸了。
这是一个插曲:http://plnkr.co/edit/fRhpsS97IGbTWtDPCMlI?p=preview
我的范围内有如下所示的数据:
$scope.data = [{
details: 'IUt euismod tellus, at posuere sem. <code lang="java">int foo = 21;</code> Nullam mattis ac elit in gravida.'
},
{
details: 'BHA BHA BHA e sem. <code lang="java">int wutWut = 56;</code> Nullam mattis ac elit in gravida. Sed nec ipsum sed urna.'
}
];
我正在这样显示数据:
<pre ng-repeat="item in data">
{{item.details}}
</pre>
一切正常,但问题是我需要将<code> 标签(来自 item.details)作为指令处理。所述指令应该读取lang 属性并使用包含的Sunlight Syntax Highlighter 正确突出显示元素的内容。
这是<code>的指令
.directive('code', ['$filter',
function($filter) {
return {
restrict: 'E',
replace: true,
scope: {
lang: '@'
},
controller: ['$scope','$element',
function($scope, $element) {
// default lang
if (typeof $scope.lang === 'undefined')
$scope.lang = 'java';
$scope.src = $element.html();
}
],
template: '<span>{{src | codeHighlight:lang}}</span>'
};
}
]);
基本上只是将这些位传递给codeHighlight 过滤器。我将它传递给过滤器的原因是因为在我的应用程序中还有一点,突出显示方法是在没有<code> 标签的情况下完成的,所以它适用于我正在做的事情(最少的代码重复)。我想我应该使用 transclude 选项和 $filter 服务,但我不是 100% 确定如何获取标签之间的值。
这是我的codeHighlight 过滤器。这使用 Sunlight lib 进行突出显示。所以它将 HTML 作为字符串返回。当我直接使用它时,我通常会这样做:ng-bind-html="foo.bar | codeHighlight | safeHtml"
.filter('codeHighlight', function() {
return function(code, lang) {
// Default lang
if (typeof lang === 'undefined')
lang = 'java';
// Grab a highlighter
var highlighter = new Sunlight.Highlighter();
var context = highlighter.highlight(code, lang);
var el = angular.element(context.getNodes());
var html = el.wrap('<p/>').parent().html();
// Convert nbsp's to actual spaces (so line breaks work better)
html = html.replace(/ /gi, ' ');
return html;
};
})
这里是 safeHtml 过滤器只是为了理智,但并不真正适用于我的问题
.filter('safeHtml', ['$sce',function($sce){
return function(html){
return $sce.trustAsHtml(html);
};
}])
所以除了原始的 data.details 之外,所有这些都可以工作,因为 Angular 不处理(正确的词是什么?我知道它没有处理)将值吐到屏幕上(原因很明显)
所以我修改了输出并创建了一个指令来重新编译输出值。我使用 compile 属性是因为我不明白如何正确拉出链接?标签之间的数据。
<pre ng-repeat="item in data" compile="item.details"></pre>
这是compile 指令
.directive('compile', ['$compile',
function($compile) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
scope.$watch(attrs.compile, function(html) {
element.html(html);
$compile(element.contents())(scope);
});
}
}
}
])
所以现在一切正常!!!好样的!除了我的 html 显示为字符串,因为 Angular 会清理输出。不幸的是,我知道如何将原始 HTML 打印到页面的唯一方法是使用 ng-bind-html 指令,因为我使用的是愚蠢的 compile 指令,所以我不能这样做。
我想也许在 watch 函数中我可以在 $compile 函数之后附加 element.html(element.html()) ,但这只是返回原始模板。
显然,我正在进入一个我不完全理解的领域。
我的梦想是像第一个示例一样设置 pre 标签:
<pre ng-repeat="item in data" compile="item.details">
{{item.details}}
</pre>
因为它看起来有点合适,但我在这里乞求不要选择。如果有人能帮助我一点点,我将非常感激。我完全被困住了,我什至不知道该谷歌什么了。
【问题讨论】:
-
你试过
element.replaceWith吗? see this question
标签: javascript angularjs angularjs-directive