因為我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鏈接修改為可點擊。這裡使用過濾器沒問題吧!
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>';