在$ http加载的内容上渲染AngularJS指令

时间:2014-08-26 13:51:28

标签: javascript angularjs angularjs-directive

我有点问题。我有一个指令

app.directive('a', function() {
    return {
        restrict: 'E',
        link: function(scope, elem, attrs) {
            elem.on('click', function(e){
                e.preventDefault();
                alert('Hyperlinks not allowed!');
            });
        }
    };
});

以及$http对包含网页内容的JSON的请求

{
    "currentNodeName":"Page 1",
    "childrenNodes":[
        {"id":"3","name":"Page 1-1"},
        {"id":"4","name":"Page 1-2"}],
    "parentNode":null,
    "currentNodeContent":[
        {"content":"<p>This is Page1. <a href=\"http://badlink.org/i/dont/want/to/work\">Link</a></p>"}],
    "currentNodeId":"1"
}

currentNodeContent已加载到div

<div id="loadedContent" ng-bind-html="boardCtrl.nodeData.currentNodeContent[0].content"></div>

现在的问题是: 如何实现加载的内容<a>标记作为指令?

感谢。

2 个答案:

答案 0 :(得分:1)

几乎正确的asnwer可以在angular ng-bind-html and directive within it找到,虽然更好的形式是:

app.directive("unsecureBind", function($compile) {
    return {
        link: function(scope, element, attrs) {
             scope.$watch(attrs.unsecureBind, function(newval) {
                  element.html(newval);
                  $compile(element.contents())(scope);
             });
        }   
    };  
});

ng-bind-html只是将数据分配给html而不运行$ compile(参见https://github.com/angular/angular.js/blob/master/src/ng/directive/ngBind.js#L197)。 这仍然是完全正确的,因为在更改值时,包含的指令不会被通知它们被销毁,因此会有更好的版本。

app.directive("unsecureBind", function($compile) {
    return {
        link: function(scope, element, attrs) {
            var childscope;
            scope.$watch(attrs.unsecureBind, function(newval, oldval) {
                if (!newval && !oldval) return; // handle first run
                if (childscope)
                    childscope.$destroy();
                element.html(newval || "");
                if (!newval) return;
                childscope = scope.$new();
                $compile(element.contents())(childscope);
            });
        }
    };
});

从角度来看这是正确的,但是:

  • 你完全违反了mvc
  • 的想法
  • 通过使用指令限制元素,您基本上将元素列入黑名单,这通常不是一个好主意,您应该使用白名单。
  • 允许用户输入成为角度运行环境的一部分也是非常不安全的。

最好通过白名单功能过滤输入html,然后将其与ng-bind-html绑定。

答案 1 :(得分:0)

Angular正在使用&#39; a&#39;作为优先指示&#39; 0&#39; (https://docs.angularjs.org/api/ng/directive/a

尝试这样做:

  • 将您的优先级设置为高于定义的值,示例1或Number.MAX_VALUE。
  • 将终端设置为true,因此不会处理较低优先级。

可以工作,我猜......:)