在AngularJs中转义&ng-bind中的字符

Dar*_*ght 18 html javascript angularjs ng-bind

我有一个用例,我们可以在字符串中包含'&'和'>'字符.例如.强生公司value > 3.因此,虽然来自服务器的响应被编码,但是该值变为'值> 3' .

ng-bind 不支持以下内容:

value > 3将呈现ngBind,而浏览器呈现相同的内容value > 3.

http://jsfiddle.net/HKahG/2/

Ng:bind <div ng-bind="model"></div> 
Ng:bind-html <div ng-bind-html="model"></div>
<div> From Div: value &gt; </div>
Run Code Online (Sandbox Code Playgroud)

为什么此默认浏览器行为不存在ng-bind?我不想使用ng-bind-html(有价值问题,<它不是一个HTML)或ng-bind-unsafe-html.

我的应用程序具有动态键值字段,将显示在应用程序的不同部分.因此,使用单独的指令或装饰器显示所有字符串字段而不是使用它将需要额外的开销ngBind.

问题:

1)有没有其他方法可以在不使用附加指令的情况下执行相同操作,或者这是处理编码数据的正确方法吗?

2)我可以覆盖ng-bind默认的行为或装饰它吗?

J. *_*uni 14

编辑:请直接到答案的底部,以获得最佳版本; 答案按时间顺序排列; 最后,我在几次迭代后获得了最佳代码.谢谢.

  • 我可以覆盖ng-bind的行为或默认装饰它吗?

是.我做了一个非常简单的实现,使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();
                    }
                }
            };
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

这不是一个"附加指令" - 这是"覆盖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 + ')';
        }
    };
}]);
Run Code Online (Sandbox Code Playgroud)

比以前的版本更清洁!当然,您可以将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';
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

现在您有三个选项可供选择.


gil*_*ly3 12

这是 HTML:

&gt;
Run Code Online (Sandbox Code Playgroud)

它可能没有HTML标签,但它仍然是HTML.如果要使用ng-bind,则服务器需要返回未编码的文本.即,>而不是&gt;.

使用ng-bind-html或修改您的服务器以返回纯文本,而不首先对其进行html编码.

编辑:快速演示,说明JavaScript中的使用&gt;和>:

div1.innerHTML = "&gt;";  // write HTML
div2.textContent = ">";   // write plain text
console.log(div1.innerHTML === div2.innerHTML);
console.log(div1.textContent === div2.textContent);
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/XhEcV/


Shr*_*ain 6

ng-bind使用.text()方法替换文本,而代码包含&gt;HTML标记时,ng-bind无法正确呈现.在实际输入HTML内容时,您应该在此处使用ng-bind-html.否则,您可以将正则表达式替换为">".

例如: - model = model.replace(/&gt;/g, '>');

但在这种情况下,您必须替换所有不需要的HTML标记,因为ng-bind-html在您的情况下已经正常工作.


Che*_*niv 5

是的,让我们用过滤器"装饰"它:

.filter("decode",function(){
    return function(str){         
      var el = document.createElement("div");
      el.innerHTML = str;
      str =   el.textContent || el.innerText;
      return str;        
    }
});
Run Code Online (Sandbox Code Playgroud)

并使用它像: <div ng-bind="model|decode"></div>

工作示例:http://jsfiddle.net/HKahG/5/

灵感来自这个答案:https://stackoverflow.com/a/784698/1206613