2013-07-10 31 views
7

我創建了一個AngularJS過濾器,用於根據數據中找到的地址自動創建可點擊的鏈接。過濾:AngularJS過濾器將html作爲字符串返回

app.filter('parseUrl', function() { 
    var //URLs starting with http://, https://, or ftp:// 
     replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim, 
     //URLs starting with "www." (without // before it, or it'd re-link the ones done above). 
     replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim, 
     //Change email addresses to mailto:: links. 
     replacePattern3 = /(\[email protected][a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim; 

     return function(text, target, otherProp) {   
      angular.forEach(text.match(replacePattern1), function(url) { 
       text = text.replace(replacePattern1, "<a href=\"$1\" target=\"_blank\">$1</a>"); 
      }); 
      angular.forEach(text.match(replacePattern2), function(url) { 
       text = text.replace(replacePattern2, "$1<a href=\"http://$2\" target=\"_blank\">$2</a>"); 
      }); 
      angular.forEach(text.match(replacePattern3), function(url) { 
       text = text.replace(replacePattern3, "<a href=\"mailto:$1\">$1</a>"); 
      }); 

      return text;   
     }; 
    }); 

這裏是我怎樣,我稱它(裏面一個段落):

<p><strong>Details:</strong> {{event.description | parseUrl}}</p> 

這正常工作,以取代中的鏈接代碼的純文本鏈接。但是,它將其替換爲純文本的鏈接。例如,www.google.com將被替換爲。這顯然不會產生可點擊的鏈接,這是我的目標。

我不知道爲什麼會發生這種情況。任何想法如何防止/修復它?謝謝。

+1

您可能想看看ngSanitize模塊中的「linky」過濾器AngularJS提供的(http://docs.angularjs.org/api/ngSanitize.filter:linky) - 該過濾器可能已經做了你需要,並且它的文檔支持在有關ng-bind-html/ng-bind-html-unsafe指令的答案中提出的建議。 – CBerube

回答

7

嘗試使用ngBindHtmlUnsafe指令有你的過濾器生產應用爲元素的實際的innerHTML內容的HTML,像這樣:

<span ng-bind-html-unsafe="event.description | parseUrl"></span> 
+4

不幸的是,在新版本的AngularJS中沒有這樣的指令 –

+0

使用'ng-bind-html-unsafe'不是一個好主意,因爲它會帶來潛在的安全風險。我認爲這是它被棄用的原因之一。 –

2

您需要使用兩種:

使用表達式會逃跑,你傳遞給它(符號如<> &)

1

我就是用這個的任何HTML實體輸出字符串的源過濾了一段時間,但不知道它產生的災難性結果。我在這裏修改版本:

filter('parseUrl', function($sce) { 
var //URLs starting with http://, https://, or ftp:// 
    replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim, 
    //URLs starting with "www." (without // before it, or it'd re-link the ones done above). 
    replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim, 
    //Change email addresses to mailto:: links. 
    replacePattern3 = /(\[email protected][a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim; 

    return function(text, target, otherProp) {   
     text = (text + '').replace(/>/,"&gt;").replace(/</,"&lt;"); 
     text = (text + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br>$2'); 
     text = text.replace(replacePattern1, "<a href=\"$1\" target=\"_blank\">$1</a>"); 
     text = text.replace(replacePattern2, "<a href=\"http://$2\" target=\"_blank\">$2</a>"); 
     text = text.replace(replacePattern3, "<a href=\"mailto:$1\">$1</a>"); 
     return $sce.trustAsHtml(text); 
    }; 
}); 

請注意,它沒有使用angular.forEach! (?????)當輸出結果時,輸出就會變成彈道。據推測,這個問題與多場比賽有關!

+0

而不是在我的主要問題中,我實際上最終使用它的一個分支:https://gist.github.com/meenie/6018010 – Jakemmarsh