搜尋

首頁  >  問答  >  主體

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:

大體的意思是:攔截一段text字段,查找裡面的http鏈接,把HTTP鏈接修改為可點擊。這裡使用過濾器沒問題吧!

漂亮男人漂亮男人2744 天前504

全部回覆(2)我來回復

  • PHPz

    PHPz2017-05-15 17:03:34

    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('<p>' + inputText + '</p>')($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>';

    回覆
    0
  • 过去多啦不再A梦

    过去多啦不再A梦2017-05-15 17:03:34

    http://stackoverflow.com/a/18149450/2586541

    回覆
    0
  • 取消回覆