我有一个用例,我们可以拥有'&'和'>'字符串中的字符。例如。约翰逊&约翰逊,value > 3
。因此,当来自服务器的响应被编码时,因此该值变为“值& gt; 3' 。
ng-bind
不支持以下内容:
value > 3
将为ngBind
呈现,而浏览器会呈现与value > 3
相同的内容。
Ng:bind <div ng-bind="model"></div>
Ng:bind-html <div ng-bind-html="model"></div>
<div> From Div: value > </div>
为什么ng-bind
中没有此默认浏览器行为?我不想使用ng-bind-html
(问题值为<
且不是html)或ng-bind-unsafe-html
。
我的应用程序具有动态键值字段,将显示在应用程序的不同部分。因此,使用单独的指令或装饰器显示所有字符串字段而不是使用ngBind
需要额外的开销。
问题:
1)是否有其他方法可以在不使用附加指令的情况下进行相同操作,或者这是处理编码数据的正确方法吗?
2)我可以覆盖ng-bind
的行为或默认装饰它吗?
答案 0 :(得分:13)
编辑:请直接到答案的底部以获得最佳版本;答案按时间顺序排列;最后,我在几次迭代后获得了最佳代码。谢谢。
是。我做了一个非常简单的实现,使ng-bind
能够按你的意愿行事。嗯......我不确定这是不是你想要的,但至少它确实是我所理解的你想要的。
工作小提琴:http://jsfiddle.net/93QQM/
以下是代码:
module.directive('ngBind', function() {
return {
compile: function(tElement, tAttrs) {
tAttrs.ngBind = 'myBind(' + tAttrs.ngBind + ')';
return {
pre: function(scope) {
scope.myBind = function(text) {
return angular.element('<div>' + text + '</div>').text();
}
}
};
}
}
});
这不是一个“附加指令” - 这是“覆盖ng-bind行为”的方法。它不添加新指令,只是扩展了现有ngBind指令的行为。
在编译函数中,我们修改ng-bind
属性的值,将其包装到函数调用中。有了这个,我们可以访问原始模型值,并有机会将其返回修改。
我们在预链接阶段通过范围提供该功能,因为如果我们在后连接阶段执行此操作,则该功能仅在 原始ngBind指令检索后可用属性中的值(将是一个空字符串,因为找不到该函数)。
myBind
函数简单明了:它创建了一个元素,文本被使用 - 未更改 - 作为元素体,只能通过text
函数立即检索 - 这将返回内容就像“浏览器呈现”一样。
这样,您可以像往常一样使用ngBind,例如<div ng-bind="model.content" />
,但具有此修改后的行为。
不是将myBind
函数附加到应用ngBind的每个范围,而是在每个预连接阶段,我们只能将它附加到$rootScope
一次,使其立即可用于所有范围。
新工作小提琴:http://jsfiddle.net/EUqP9/
新代码:
module.directive('ngBind', ['$rootScope', function($rootScope) {
$rootScope.myBind = function(text) {
return angular.element('<div>' + text + '</div>').text();
};
return {
compile: function(tElement, tAttrs) {
tAttrs.ngBind = 'myBind(' + tAttrs.ngBind + ')';
}
};
}]);
比以前的版本更清洁!当然,您可以将myBind
函数名称更改为您想要的任何其他名称。该功能的“成本”是这样的:将这个简单的功能添加到根范围 - 由您来决定它是否物有所值。
受Chemiv的回答影响...为什么不从任何范围删除该功能并将其改为过滤器?它也有效。
又一个新的工作小提琴:http://jsfiddle.net/hQJaZ/
新代码:
module.filter('decode', function() {
return function(text) {
return angular.element('<div>' + text + '</div>').text();
};
}).directive('ngBind', function() {
return {
compile: function(tElement, tAttrs) {
tAttrs.ngBind += '|decode';
}
};
});
现在您有三个选项可供选择。
答案 1 :(得分:12)
此是 HTML:
>
它可能没有HTML标记,但它仍然是HTML。如果要使用ng-bind
,则服务器需要返回未编码的文本。即>
而不是>
。
使用ng-bind-html
或修改服务器以返回纯文本,而不先对其进行html编码。
修改:快速演示,说明在JavaScript中使用>
和>
:
div1.innerHTML = ">"; // write HTML
div2.textContent = ">"; // write plain text
console.log(div1.innerHTML === div2.innerHTML);
console.log(div1.textContent === div2.textContent);
答案 2 :(得分:6)
ng-bind使用.text()方法替换文本,而代码包含>
,这是HTML标记,但ng-bind无法正确呈现。在实际输入HTML内容时,您应该在此处使用ng-bind-html。否则你可以替换&gt;正则表达式为'&gt;'。
例如: - model = model.replace(/>/g, '>');
但在这种情况下,您必须替换所有不需要的HTML标记,因为在您的情况下ng-bind-html已经正常工作。
答案 3 :(得分:5)
是的,让我们用过滤器“装饰”它:
.filter("decode",function(){
return function(str){
var el = document.createElement("div");
el.innerHTML = str;
str = el.textContent || el.innerText;
return str;
}
});
并使用它:<div ng-bind="model|decode"></div>
答案 4 :(得分:1)
我记得有一个名为ngBindHtmlUnsafe的指令可用于此类用例。
http://code.angularjs.org/1.0.8/docs/api/ng.directive:ngBindHtmlUnsafe
请参阅此。不确定这是否在以后的不稳定版本中可用。 这是最新稳定版本的链接。
答案 5 :(得分:0)
为什么不使用$ sce.trustAsHtml?