Html 在 AngularJs 中的 ng-bind 中转义 & > 字符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19264586/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Escaping & > characters in ng-bind in AngularJs
提问by DarkKnight
I have a use case, where we can have '&' and '>' characters in a string. eg. Johnson & Johnson, value > 3
. So while the response from server is encoded, hence the value becomes 'value > 3'.
我有一个用例,我们可以在字符串中包含 '&' 和 '>' 字符。例如。强生公司,value > 3
。因此,当来自服务器的响应被编码时,因此该值变为 'value > 3'。
ng-bind
doesn't support the following:
ng-bind
不支持以下内容:
value > 3
will be rendered for ngBind
, whereas the browser renders the same content as value > 3
.
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>
Why is this default browser behavior not present in ng-bind
?. I don't want to use ng-bind-html
(has issues with value <
and it is not a html) or ng-bind-unsafe-html
.
为什么ng-bind
? 中不存在此默认浏览器行为。我不想使用ng-bind-html
(价值有问题,<
它不是 html)或ng-bind-unsafe-html
.
My application has dynamic key-value fields which will be displayed in different parts of the application. So it will require additional overhead to use a separate directive or decorator to display all string fields than to use ngBind
.
我的应用程序具有动态键值字段,它们将显示在应用程序的不同部分。因此,使用单独的指令或装饰器来显示所有字符串字段比使用ngBind
.
Questions:
问题:
1) Is there any other way of doing the same without using an additional directive, or is this the right way of handling encoded data?
1)有没有其他方法可以在不使用额外指令的情况下做同样的事情,或者这是处理编码数据的正确方法?
2) Can I override the behavior of ng-bind
or decorate it by default?
2)我可以ng-bind
默认覆盖或装饰它的行为吗?
回答by J. Bruni
EDIT: please, go straight to the bottom of the answer to get the best version; the answer is at chronological order; I got the optimal code after a few iterations, at the end. Thank you.
编辑:请直接到答案的底部以获得最佳版本;答案是按时间顺序排列的;经过几次迭代,我最终得到了最佳代码。谢谢你。
- Can I override the behaviour of ng-bind or decorate it by default ?
- 我可以覆盖 ng-bind 的行为或默认装饰它吗?
Yes. I've done a very simple implementation which makes ng-bind
to behave as you want. Well... I'm not sure if this is exactly what you want, but at least it does what I've understood you want.
是的。我已经完成了一个非常简单的实现,它可以ng-bind
按照您的意愿行事。嗯......我不确定这是否正是你想要的,但至少它做了我理解你想要的。
Working fiddle: http://jsfiddle.net/93QQM/
工作小提琴:http: //jsfiddle.net/93QQM/
And here is the code:
这是代码:
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();
}
}
};
}
}
});
This is not exactly an "additional directive" - this is the way to "override the behaviour of ng-bind". It does not add a new directive, it just extends behaviour of existent ngBind directive.
这不完全是一个“附加指令”——这是“覆盖 ng-bind 行为”的方法。它不添加新指令,它只是扩展现有 ngBind 指令的行为。
At the compilefunction, we modify the value of the ng-bind
attribute, wrapping it into a function call. With this, we have access to the original model value, and the opportunity to return it modified.
在compile函数中,我们修改ng-bind
属性的值,将其包装到函数调用中。有了这个,我们可以访问原始模型值,并有机会将其返回修改。
We make the function available through the scope in the pre-linking phase, because if we do this in the post-linking phase, the function will be available only afterthe original ngBind directive has retrieved the value from the attribute (which will be an empty string, because the function wil not be found).
我们在预链接阶段通过作用域使函数可用,因为如果我们在链接后阶段这样做,只有在原始 ngBind 指令从属性中检索到值(这将是一个空字符串,因为找不到该函数)。
The myBind
function is simple and smart: it creates an element, and the text is used - unchanged - as the element body, only to be immediately retrieved through the text
function - which will return the contents just as "the browser renders" it.
该myBind
函数简单而智能:它创建了一个元素,文本被用作元素主体——不变——作为元素主体,只是通过text
函数立即检索——它将返回内容,就像“浏览器呈现”它一样。
This way, you can use ngBind as usual, like <div ng-bind="model.content" />
, but have this modified behaviour.
这样,您可以像往常一样使用 ngBind,例如<div ng-bind="model.content" />
,但要修改行为。
Improved version
改良版
Instead of attaching the myBind
function to every scope where ngBind is applied, at every pre-linking phase, we can attach it only once to the $rootScope
, making it immediately available for all scopes.
不是将myBind
函数附加到应用 ngBind 的每个作用域,在每个预链接阶段,我们只能将它附加一次到$rootScope
,使其立即可用于所有作用域。
New working fiddle: http://jsfiddle.net/EUqP9/
新工作小提琴:http: //jsfiddle.net/EUqP9/
New code:
新代码:
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 + ')';
}
};
}]);
Much cleaner than the previous version! Of course, you can change myBind
function name to any other name you want. The "cost" of the feature is this: have this simple function added to the root scope - it is up to you to decide if it worths the price.
比之前的版本干净多了!当然,您可以将myBind
函数名称更改为您想要的任何其他名称。该功能的“成本”是这样的:将这个简单的功能添加到根范围 - 由您决定是否值得付出代价。
Yet another version
又一个版本
Influenced by Chemiv's answer... why not remove the function from any scope and make it a filter instead? It also works.
受 Chemiv 答案的影响......为什么不从任何范围中删除该函数并使其成为过滤器呢?它也有效。
Yet another new working fiddle: http://jsfiddle.net/hQJaZ/
另一个新的工作小提琴:http: //jsfiddle.net/hQJaZ/
And the new code:
和新代码:
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';
}
};
});
Now you have three options to choose from the menu.
现在您可以从菜单中选择三个选项。
回答by gilly3
This isHTML:
这是HTML:
>
It may not have HTML tags, but it's still HTML. If you want to use ng-bind
, your server needs to return unencoded text. Ie, >
instead of >
.
它可能没有 HTML 标签,但它仍然是 HTML。如果您想使用ng-bind
,您的服务器需要返回未编码的文本。即,>
而不是>
。
Use ng-bind-html
or modify your server to return plain text without html encoding it first.
使用ng-bind-html
或修改您的服务器以返回纯文本,而无需先对其进行 html 编码。
Edit:Quick demo that illustrates the use of >
and >
in JavaScript:
编辑:快速演示,说明JavaScript中>
和>
的使用:
div1.innerHTML = ">"; // write HTML
div2.textContent = ">"; // write plain text
console.log(div1.innerHTML === div2.innerHTML);
console.log(div1.textContent === div2.textContent);
回答by Shreyance Jain
ng-bind uses .text() method to replace text and while your code contains >
which is HTML markup it is not correctly rendered by ng-bind. You should use ng-bind-html in this place as you are actually entering HTML content. Otherwise you can replace > by regex to '>'.
ng-bind 使用 .text() 方法替换文本,虽然您的代码包含>
HTML 标记,但 ng-bind 无法正确呈现。你应该在这个地方使用 ng-bind-html 因为你实际上是在输入 HTML 内容。否则,您可以将 > 用正则表达式替换为“>”。
ex :- model = model.replace(/>/g, '>');
前任 :- model = model.replace(/>/g, '>');
But in this case you have to replace all HTML markups which is not needed since ng-bind-html is already working fine in your case.
但是在这种情况下,您必须替换所有不需要的 HTML 标记,因为 ng-bind-html 在您的情况下已经可以正常工作。
回答by Cherniv
Yes , let's "decorate" it with a filter:
是的,让我们用过滤器“装饰”它:
.filter("decode",function(){
return function(str){
var el = document.createElement("div");
el.innerHTML = str;
str = el.textContent || el.innerText;
return str;
}
});
And use it like: <div ng-bind="model|decode"></div>
并像这样使用它: <div ng-bind="model|decode"></div>
Working example: http://jsfiddle.net/HKahG/5/
工作示例:http: //jsfiddle.net/HKahG/5/
Inspired by this answer: https://stackoverflow.com/a/784698/1206613
回答by Arshabh Agarwal
I remember a directive named ngBindHtmlUnsafe available for such use cases.
我记得有一个名为 ngBindHtmlUnsafe 的指令可用于此类用例。
http://code.angularjs.org/1.0.8/docs/api/ng.directive:ngBindHtmlUnsafe
http://code.angularjs.org/1.0.8/docs/api/ng.directive:ngBindHtmlUnsafe
Please refer to this. Not sure if this is available in later unstable releases. This is link to the latest stable release available.
请参考这个。不确定这在以后的不稳定版本中是否可用。这是可用的最新稳定版本的链接。
回答by Bob Barker
Why not just use $sce.trustAsHtml?
为什么不直接使用 $sce.trustAsHtml?