2013-07-10 45 views
7

Tôi đã tạo bộ lọc AngularJS để tự động tạo liên kết có thể nhấp từ các địa chỉ được tìm thấy trong dữ liệu. Bộ lọc:Bộ lọc AngularJS trả về html dưới dạng chuỗi

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;   
     }; 
    }); 

Và đây là cách tôi gọi đó là (bên trong một đoạn văn):

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

Và làm việc này một cách chính xác để thay thế các liên kết văn bản đơn giản với mã cho một liên kết. Tuy nhiên, nó thay thế nó bằng liên kết theo nghĩa đen là văn bản thuần túy. Ví dụ: www.google.com sẽ được thay thế bằng . Điều này rõ ràng không tạo ra một liên kết có thể nhấp, đó là mục tiêu của tôi.

Tôi không chắc tại sao điều này lại xảy ra. Bất kỳ ý tưởng về cách ngăn chặn/sửa chữa nó? Cảm ơn.

+1

Bạn có thể xem bộ lọc "liên kết" mà AngularJS cung cấp (http://docs.angularjs.org/api/ngSanitize.filter:linky) trong mô-đun ngSanitize - bộ lọc đó có thể đã làm những gì bạn cần, và tài liệu cho nó hỗ trợ các đề xuất được đưa ra trong các câu trả lời liên quan đến lệnh ng-bind-html/ng-bind-html-unsafe. – CBerube

Trả lời

7

Hãy thử sử dụng các chỉ thị ngBindHtmlUnsafe để có HTML rằng bộ lọc của bạn tạo ra áp dụng như nội dung innerHTML thực tế của một phần tử, như vậy:

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

Thật không may là không có chỉ thị như vậy trong phiên bản mới của AngularJS –

+0

Nó không phải là một ý tưởng tốt để sử dụng 'ng-bind-html-unsafe' vì nó sẽ mang lại rủi ro bảo mật tiềm năng. Tôi nghĩ đây là một trong những lý do tại sao nó không được chấp nhận. –

2

Bạn cần phải sử dụng một trong hai:

  • ngBindHtmlUnsafe
    Nếu bạn tin cậy 100% nguồn nội dung
  • ngBindHtml
    Nếu bạn không tin tưởng vào nguồn gốc của nội dung

Xuất ra một chuỗi sử dụng một biểu thức sẽ thoát khỏi bất kỳ thực thể html mà bạn vượt qua nó (biểu tượng như <> &)

1

Tôi đã sử dụng này lọc một lúc, bằng cách nào đó mà không chú ý đến kết quả tai hại mà nó tạo ra. Phiên bản đã sửa đổi của tôi ở đây:

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); 
    }; 
}); 

Lưu ý rằng nó không sử dụng góc cạnh.forEach! (?????) Đầu ra sẽ đi đạn đạo khi nó. Có lẽ vấn đề này phải làm với việc có nhiều trận đấu!

+0

Thay vì câu hỏi chính của tôi, tôi thực sự đã sử dụng một cái nĩa của nó: https://gist.github.com/meenie/6018010 – Jakemmarsh

Các vấn đề liên quan