逃避& > AngularJs中ng-bind中的字符

时间:2013-10-09 06:21:52

标签: javascript html angularjs ng-bind

我有一个用例,我们可以拥有'&'和'>'字符串中的字符。例如。约翰逊&约翰逊,value > 3。因此,当来自服务器的响应被编码时,因此该值变为“值& gt; 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>

为什么ng-bind中没有此默认浏览器行为?我不想使用ng-bind-html(问题值为<且不是html)或ng-bind-unsafe-html

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

问题:

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

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

6 个答案:

答案 0 :(得分:13)

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

  • 我可以覆盖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();
                    }
                }
            };
        }
    }
});

这不是一个“附加指令” - 这是“覆盖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:

&gt;

它可能没有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);

http://jsfiddle.net/XhEcV/

答案 2 :(得分:6)

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

例如: - model = model.replace(/&gt;/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>

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

受到这个答案的启发:https://stackoverflow.com/a/784698/1206613

答案 4 :(得分:1)

我记得有一个名为ngBindHtmlUnsafe的指令可用于此类用例。

http://code.angularjs.org/1.0.8/docs/api/ng.directive:ngBindHtmlUnsafe

请参阅此。不确定这是否在以后的不稳定版本中可用。 这是最新稳定版本的链接。

答案 5 :(得分:0)

为什么不使用$ sce.trustAsHtml?