2013-07-10 14 views
7

Ho creato un filtro AngularJS per creare automaticamente collegamenti selezionabili dagli indirizzi trovati nei dati. Il filtro:Filtro AngularJS che restituisce html come stringa

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

Ed ecco come sto chiamando (all'interno di un paragrafo):

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

E questo funziona correttamente per sostituire i collegamenti di testo con il codice per un collegamento. Tuttavia, lo sostituisce con il link letteralmente come testo normale. Ad esempio, www.google.com verrà sostituito con . Questo chiaramente non rende un link cliccabile, che era il mio obiettivo.

Non sono sicuro del motivo. Qualche idea su come prevenirlo/risolverlo? Grazie.

+1

Si consiglia di dare un'occhiata al filtro "linky" che fornisce AngularJS (http://docs.angularjs.org/api/ngSanitize.filter:linky) nel modulo ngSanitize - quel filtro potrebbe già fare ciò che si necessario, e la documentazione per esso supporta i suggerimenti formulati nelle risposte riguardanti le direttive ng-bind-html/ng-bind-html-non sicure. – CBerube

risposta

7

provare ad utilizzare la direttiva ngBindHtmlUnsafe di avere il codice HTML che il filtro produce applicato come effettivi contenuti innerHTML di un elemento, in questo modo:

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

Sfortunatamente non esiste una direttiva di questo tipo nella nuova versione di AngularJS –

+0

Non è una buona idea usare 'ng-bind-html-unsafe' poiché potrebbe causare potenziali rischi per la sicurezza. Penso che questo sia stato uno dei motivi per cui è stato deprecato. –

2

è necessario utilizzare uno:

  • ngBindHtmlUnsafe
    Se ti fidi al 100% dell'origine del contenuto
  • ngBindHtml
    Se non si considera attendibile l'origine del contenuto

Output una stringa utilizzando un'espressione sfuggirà qualsiasi entità HTML che si passa a esso (simboli come <> &)

1

stavo usando questo filtro per un po ', in qualche modo senza notare i risultati disastrosi che ha prodotto. La mia versione modificata qui:

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

Si noti che non sta utilizzando angular.for Any! (?????) L'output sarebbe balistico quando lo ha fatto. Presumibilmente questo problema ha a che fare con più corrispondenze!

+0

Invece di quello nella mia domanda principale, in realtà ho finito per usare un fork di esso: https://gist.github.com/meenie/6018010 – Jakemmarsh

Problemi correlati