【问题标题】:Angular $compile throws error for non-HTML string with quotesAngular $compile 对带引号的非 HTML 字符串抛出错误
【发布时间】:2016-07-20 17:25:13
【问题描述】:

我正在尝试使用$compile 将用户提供的 HTML 注入指令中。

module.directive('foo', ["$compile", function($compile) {
    return {
        // ...
        link: function($scope, el) {
            // ...
            var userHtml = userConfigObject.content;
            var compiledHtml = $compile(userHtml)($scope);
            myElement.innerContent.html(compiledHtml);
        }
    };
 }]);

我想允许用户注入一个字符串(例如"Let's party!")或一些HTML(例如'<div ng-click="foo()">Click to party!</div>')。

但是,当用户只提供带引号的字符串(或任何其他“无效 HTML”)时,$compile 语句会给出以下错误:

语法错误,无法识别的表达式:让我们一起狂欢吧!

(这个错误最终来自 jQuery 的 Sizzle 逻辑)。

我能想到解决这个问题的唯一方法(同时仍然允许非 HTML 和 HTML 字符串)是使用它来代替。

var stepHtml = '<div>' + userConfigObject.content + '</div>';

这样$compile 总是会收到一个有效的 HTML 字符串。但是,我宁愿不要将内容不必要地包装在 div 中。

无效的解决方案

我尝试预先转义用户内容(用 HTML 代码替换引号),但没有奏效。

我也尝试使用$sanitize,认为它会转义字符或其他东西,但这也没有用。

最后,当我使用$interpolate 时,ng-click 属性不起作用。

关于如何在非 HTML 字符串上使用 $compile 有什么想法吗?还是我看错了?

【问题讨论】:

    标签: javascript jquery angularjs angularjs-directive


    【解决方案1】:

    如果用户实际上输入了 ng-click 之类的指令,那么您可以查看 html 中是否包含元素:

    var userHtml = userConfigObject.content;
    var $tempDiv  = angular.element('<div>').html(userHtml);
    if(!$tempDiv.children().length){
      userHtml = $tempDiv 
    }
    
    var compiledHtml = $compile(userHtml)($scope);
    myElement.innerContent.html(compiledHtml);
    

    如果有文本节点与根中的元素混合,那么你最好的选择总是包装在一个容器中

    【讨论】:

    • 但是 OP 也想让ng-click 工作,这就是他手动选择$compileing 元素的原因。我认为他应该将userConfigObject.content 传递给一些对HTML 进行编码的函数,以便他可以正确地$compile 该字符串
    • @PankajParkar 好的......我现在有解决方案
    • @PankajParkar 可能仍然是问题,如果根中的文本节点以及元素。不太确定,也没有足够的好奇心来构建测试
    • 但是我们还是用 div 包装内容.. 所以我不认为这会发生
    • @PankajParkar 不确定。想想"Click to party!&lt;span&gt;Click here&lt;/span&gt;"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    • 2018-08-11
    相关资源
    最近更新 更多