18

我有一个用例,我们可以在字符串中包含 '&' 和 '>' 字符。例如。强生公司,value > 3. 因此,虽然来自服务器的响应被编码,但值变为 'value > 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默认覆盖或装饰它的行为吗?

4

6 回答 6

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();
                    }
                }
            };
        }
    }
});

这不完全是一个“附加指令”——这是“覆盖 ng-bind 的行为”的方式。它不会添加新指令,它只是扩展现有 ngBind 指令的行为。

compile函数中,我们修改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';
        }
    };
});

现在您可以从菜单中选择三个选项。

于 2013-10-12T02:31:33.027 回答
12

HTML:

&gt;

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

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

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

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/

于 2013-10-09T09:06:20.370 回答
6

ng-bind 使用 .text() 方法替换文本,虽然您的代码包含&gt;HTML 标记,但 ng-bind 未正确呈现。你应该在这个地方使用 ng-bind-html,因为你实际上是在输入 HTML 内容。否则,您可以将 > 替换为 '>'。

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

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

于 2013-10-16T14:20:36.733 回答
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

于 2013-10-09T07:56:13.013 回答
1

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

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

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

于 2013-10-14T11:10:09.650 回答
0

为什么不直接使用 $sce.trustAsHtml?

于 2015-09-19T05:07:06.413 回答