我正试图在我的角度应用中使用prismjs 这是我到目前为止所得到的
app.directive('nagPrism', [function() {
return {
restrict: 'A',
transclude: true,
scope: {
source: '='
},
link: function(scope, element, attrs, controller, transclude) {
if(!scope.source) {
transclude(function(clone) {
element.html(clone);
Prism.highlightElement(element.find("code")[0]);
});
} else {
scope.$watch(function() {return scope.source;}, function(v) {
if(v) {
Prism.highlightElement(element.find("code")[0]);
}
});
}
},
template: "<code ng-bind='source'></code>"
};
}]);
如果我有这样的东西,这将有效
<!-- This works -->
<pre nag-prism source="code" class="language-css"></pre>
但是我想让它也适合这样的事情
<pre nag-prism class="language-css">
<code>body {
color: red;
}
{{code}}
</code>
</pre>
为方便起见,我做了一个plunkr 有什么提示吗?
答案 0 :(得分:9)
据我所知,你的目标是构建一个突出显示代码的指令,这些代码既可以作为常量给定,也可以通过变量或上面两种混合使用。如果您没有附上帖子的语法,这里有解决方案。
主要问题是在应用Prism高亮显示功能之前,需要编译代码模板以便将{{variables}}更改为它们的值。在您的解决方案中,突出显示功能将应用于原始模板。
我们的想法是将绑定类型从'='更改为'@',并在所有情况下将源代码作为属性传递。
旧约束:
scope: {
source: '='
}
新绑定:
scope: {
source: '@'
}
Angular文档:
@或@attr - 将本地范围属性绑定到DOM的值 属性。由于DOM属性,结果总是一个字符串 字符串。如果未指定attr名称,则属性名称为 假设与本地名称相同。给定和小部件定义 范围:{localName:'@ myAttr'},然后是widget范围属性 localName将反映hello {{name}}的内插值。如 name属性更改,因此localName属性将更改 小部件范围。从父作用域(而不是组件)读取名称 范围)。
更新了html示例(请注意第一个示例中的旧绑定也已更改!):
<!-- This works -->
<pre nag-prism source="{{code}}" class="language-css"></pre>
<!-- Now this works either! -->
<pre nag-prism source="body {
color: red;
}
{{code}}" class="language-css"></pre>
完整更新的指令代码:
app.directive('nagPrism', [function() {
return {
restrict: 'A',
scope: {
source: '@'
},
link: function(scope, element, attrs) {
scope.$watch('source', function(v) {
if(v) {
Prism.highlightElement(element.find("code")[0]);
}
});
},
template: "<code ng-bind='source'></code>"
};
}]);
您可以在此处找到有效的解决方案:working sample
编辑:指示已更新,以符合以下评论中的目标
为了正确显示已删除的内容,必须手动编译。它会导致指令代码发生一些变化(如果版本不为空且未定义源,则下面的版本使用已转换的内容):
app.directive('nagPrism', ['$compile', function($compile) {
return {
restrict: 'A',
transclude: true,
scope: {
source: '@'
},
link: function(scope, element, attrs, controller, transclude) {
scope.$watch('source', function(v) {
element.find("code").html(v);
Prism.highlightElement(element.find("code")[0]);
});
transclude(function(clone) {
if (clone.html() !== undefined) {
element.find("code").html(clone.html());
$compile(element.contents())(scope.$parent);
}
});
},
template: "<code></code>"
};
}]);
以下示例添加了绑定到输入的代码块,以显示链接有效:improved sample
答案 1 :(得分:4)
您只需要在执行控制器后重新加载Prism插件。
app.controller('StartController', ['$scope', function($scope){
console.log('hello');
Prism.highlightAll(); // Only this that you need do!
}]);
答案 2 :(得分:0)
将其添加到$ stateChangeSuccss事件处理程序
中app.run(function($rootScope $timeout){
$rootScope.$on('$stateChangeSuccess', function() {
$timeout(function() {Prism.highlightAll()}, 0);
});