angular.js - angularjs compile问题

查看:147
本文介绍了angular.js - angularjs compile问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

因为我ng-bind-html用到了ng-click,需要用compile,但是我看的文档都是在directive里面写compile,问题是我是在过滤器filter里面用compile,怎么用啊,网上一点资源都找不到。

app.filter('httpClickFilter',function($sce){
        return function(inputText){
            var textHttpArray = inputText.split('http');
            textHttpArray[textHttpArray.length-1] = textHttpArray[textHttpArray.length-1] + ' ';
            for(var i = 1;i < textHttpArray.length; i++){
                var textSubstring = 'http' + textHttpArray[i].substring(0,textHttpArray[i].indexOf(' '));
                var replaceTextHttp = "<span style='color:#fe7979' ng-click='httpLinkClick()'>"+textSubstring+"</span>";
                inputText = inputText.replace(textSubstring,replaceTextHttp);
            }
            return $sce.trustAsHtml(inputText);
        }
    })

HTML:<span ng-bind-html="item.text | httpClickFilter"></span>

大体的意思是:拦截一段text字段,查找里面的http链接,把HTTP链接修改为可点击。这里使用过滤器没问题吧!

解决方案

http://stackoverflow.com/questions/19726179/how-to-make-ng-bind-html-compile-angularjs-code

补充

如果只是单纯的进行数据转换,这里用filter无疑是正确的选择。但是你这里牵扯到了ng-click这种动态的事件绑定,这时候还想着用filter去处理这种需求是不适合的。filter是对我们的输入进行额外的处理,针对的是数据,注意了,是针对数据,职责很明确,如果你拿filter处理渲染的逻辑违反了单一职责原则,这并不是angular设计filter的初衷。

OK,如果你硬要写在filter里,那么httpLinkClick方法只能挂在到$rootScope上,没有别的选择,HACK一个实现

app.filter('httpClickFilter', function ($sce, $compile, $rootScope) {
    $rootScope.httpLinkClick = function () {
        console.log(234);
    };

    return function (inputText) {
        var textHttpArray = inputText.split('http');
        textHttpArray[textHttpArray.length - 1] = textHttpArray[textHttpArray.length - 1] + ' ';
        for (var i = 1; i < textHttpArray.length; i++) {
            var textSubstring = 'http' + textHttpArray[i].substring(0, textHttpArray[i].indexOf(' '));
            var replaceTextHttp = "<span style='color:#fe7979' ng-click='httpLinkClick()'>" + textSubstring + "</span>";
            inputText = inputText.replace(textSubstring, replaceTextHttp);
        }

        return $sce.trustAsHtml($compile('<div>' + inputText + '</div>')($rootScope).html());
    }
});

不过很可惜,没有用,因为trustAsHtml将绑定的事件都处理掉了。

很明显这种需求需要使用指令去实现,你要明白,每种功能都有自己的使用场景。

app.directive('httpClick', function ($compile) {
    return {
        restrict: 'A',
        scope: {
            contents: '=httpClick'
        },
        link: function (scope, element, attrs) {
            var inputText = scope.contents;
            var textHttpArray = inputText.split('http');
            textHttpArray[textHttpArray.length - 1] = textHttpArray[textHttpArray.length - 1] + ' ';
            for (var i = 1; i < textHttpArray.length; i++) {
                var textSubstring = 'http' + textHttpArray[i].substring(0, textHttpArray[i].indexOf(' '));
                var replaceTextHttp = "<span style='color:#fe7979' ng-click='httpLinkClick()'>" + textSubstring + "</span>";
                inputText = inputText.replace(textSubstring, replaceTextHttp);
            }

            element.html($compile(inputText)(scope));
        },
        controller: function ($scope) {
            $scope.httpLinkClick = function () {

            }
        }
    }
})

题外话

如果text的来自用户输入,那么你要注意XSS攻击了,试着使用下面的text

$scope.text = 'http://www.baidu.com<script>alert(4)</script>';

这篇关于angular.js - angularjs compile问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆