typescript Angular2 将纯文本转换为 url 的方式(锚链接)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39276617/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular2 way of converting plain text to url (anchor links)
提问by CommonSenseCode
I sometimes have a component that can receive text like this:
我有时有一个组件可以接收这样的文本:
text www.website.com
文字 www.website.com
But I would like to convert it to a url if it is a link. Like this.
但如果它是链接,我想将其转换为 url。像这样。
text www.website.com
I read this SO answerthat suggests using 3rd party libs such as anchorme. Is there anywway to do it the angular2 way?
采纳答案by tuomassalo
There are numerous problems with using simple regexes to modify HTML content.
使用简单的正则表达式修改 HTML 内容存在许多问题。
Here's an approach that uses the linkifyjsmodule, which you need to npm install
. Do notice that the input is considered plain text, while output is HTML text.
这是一种使用linkifyjs模块的方法,您需要使用它npm install
。请注意,输入被视为纯文本,而输出是 HTML 文本。
import { Pipe, PipeTransform } from '@angular/core';
import linkifyStr from 'linkifyjs/string';
@Pipe({name: 'linkify'})
export class LinkifyPipe implements PipeTransform {
transform(str: string): string {
return str ? linkifyStr(str, {target: '_system'}) : str;
}
}
NB: If you need to specify the target
attributes, add eg. {target: '_system'}
as a second parameter to linkifyStr
.
注意:如果您需要指定target
属性,请添加例如。{target: '_system'}
作为 的第二个参数linkifyStr
。
回答by Mark Acosta
Okay so to make a pipe you would make a pipe component consisting of
好的,所以要制作管道,您将制作一个管道组件,包括
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'linkify'})
export class LinkifyPipe implements PipeTransform {
transform(link: string): string {
return this.linkify(link);
}
private linkify(plainText): string{
let replacedText;
let replacePattern1;
let replacePattern2;
let replacePattern3;
//URLs starting with http://, https://, or ftp://
replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
replacedText = plainText.replace(replacePattern1, '<a href="" target="_blank"></a>');
//URLs starting with "www." (without // before it, or it'd re-link the ones done above).
replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
replacedText = replacedText.replace(replacePattern2, '<a href="http://" target="_blank"></a>');
//Change email addresses to mailto:: links.
replacePattern3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
replacedText = replacedText.replace(replacePattern3, '<a href="mailto:"></a>');
return replacedText;
}
}
then import this like u would a directive, pass it to the
然后像你导入一个指令一样导入它,将它传递给
pipes: [LinkifyPipe]
and interpolate like this
并像这样插入
{{url | linkify}}
回答by Co?kun Deniz
you should use this pipe in this way:
你应该这样使用这个管道:
<div [innerHtml]="note.title | linkify"></div>
<div [innerHtml]="note.title | linkify"></div>
回答by Doua Beri
You should check angular-linky https://github.com/dzonatan/angular-linky
你应该检查 angular-linky https://github.com/dzonatan/angular-linky
<span [innerHTML]="yourText | linky"></span>
回答by Elroy
I have searched for a solution but to no avail. I needed to extent the requirement to handle Angular routing [routerLink] and external links with [innerHTML] without the need for 3rd party libs.
我已经寻找了解决方案,但无济于事。我需要扩展处理 Angular 路由 [routerLink] 和带有 [innerHTML] 的外部链接的需求,而不需要 3rd 方库。
My solution (summary):
我的解决方案(总结):
Angular 2, Angular 5 - User click events/event handling for dynamic [innerHTML] generated content using pipe and directive to generate and converting plain text to click urls e.g #hashtags, @Handle, @Mention, #routerLink #href and #mailto etc
Angular 2、Angular 5 - 动态 [innerHTML] 生成内容的用户单击事件/事件处理使用管道和指令生成纯文本并将其转换为单击 url,例如 #hashtags、@Handle、@Mention、#routerLink #href 和 #mailto 等
Plunker demo:https://embed.plnkr.co/68lZFY/
Plunker 演示:https ://embed.plnkr.co/68lZFY/
AppComponent
应用组件
import { Component, NgModule, VERSION} from '@angular/core';
import { BrowserModule} from '@angular/platform-browser';
@Component({
selector: 'my-app',
template: `<h1>Angular - Dynamic content click event</h1>
<p>Angular 2, Angular 5, Typescript - User click events/event handling for dynamic [innerHTML] generated content using pipe and directive to generate and converting plain text to click urls e.g #hashtags, @Handle, @Mention, #routerLink #href and #mailto etc</p>
<ul>
<li *ngFor="let item of theList; let $index=index;" [innerHTML]="item | parseUrl" [dynamicContent]="currentView"></li>
<ul>`
})
export class AppComponent {
theList:Array;
constructor() {
this.theList = [
'Lorem ipsum dolor sit amet, consectetur @adet dolore magna aliqua. Ut enim ad minim veniam',
'Lorem ipsum dolor sit amet, consectetur adipiscing http://google.com sed do eiusmod tempor #incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam',
'Lorem http://google.com ipsum dolor #sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt gna aliqua. Ut enim ad minim veniam',
'Lorem ipsum @dolor sit amet, consectetur @adipiscing elit, sed do eiusmod @tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam',
'Lorem ipsum dolor sit amet, smod tempor incididunt #ut labore et dolore @magna #aliqua. Ut enim ad minim veniam',
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam',
'Lorem ipsum @dolor sit amet, #consectetur adipiscing elit, sed do eiusmod tempor http://google.com enim ad minim veniam'
];
}
}
Directive
指示
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[dynamicContent]'
})
export class DynamicContent {
constructor(private el: ElementRef) { }
@Input('dynamicContent') dynamicContent: string;
@HostListener('click', ['$event']) onClick(e) {
if (e.target.classList.contains('handle-link')) {
let link: string = e.target.innerHTML;
event.preventDefault();
event.stopPropagation();
alert("/search/handle/" + link.trim());
//this.router.navigateByUrl("/search/handle/" + link.trim(), { skipLocationChange: false });
} else if (e.target.classList.contains('hashtag-link')) {
let link: string = e.target.innerHTML;
event.preventDefault();
event.stopPropagation();
alert("/search/hashtag/" + link.trim());
//this.router.navigateByUrl("/search/hashtag/" + link.trim(), { skipLocationChange: false });
}
}
}
Pipe
管道
export class ParseUrl implements PipeTransform {
urls: any = /(\b(https?|http|ftp|ftps|Https|rtsp|Rtsp):\/\/[A-Z0-9+&@#\/%?=~_|!:,.;-]*[-A-Z0-9+&@#\/%=~_|])/gim; // Find/Replace URL's in text
hashtags: any = /(^|\s)(#[a-z\d][\w-]*)/ig; // Find/Replace #hashtags in text
mentions: any = /(^|\s)(@[a-z\d][\w-]*)/ig; // Find/Replace @Handle/Mentions in text
emails: any = /(\S+@\S+\.\S+)/gim; // Find/Replace email addresses in text
transform(text: string) {
return this.parseUrl(text);
}
private parseUrl(text: string) {
// Find/Replace URL's in text
if (text.match(this.urls)) {
text = text.replace(this.urls, function replacer(, , ) {
let url: any = ;
let urlClean: any = url.replace("" + + "://", "");
return "<a href=\"" + url + "\" target=\"_blank\">" + urlClean + "</a>";
});
}
// Find/Replace @Handle/Mentions in text
if (text.match(this.hashtags)) {
text = text.replace(this.hashtags, "<a href=\"/search/hashtag/\" class=\"hashtag-link\"></a>");
}
// Find/Replace #hashtags in text
if (text.match(this.mentions)) {
text = text.replace(this.mentions, "<a href=\"/search/handle/\" class=\"handle-link\"></a>");
}
// Find/Replace email addresses in text
if (text.match(this.emails)) {
text = text.replace(this.emails, "<a href=\"mailto:\"></a>");
}
return text;
}
}
回答by CommonSenseCode
Ok this is how I did it leaving answer hope it helps someone else:
好的,这就是我这样做的方式,留下答案希望它可以帮助其他人:
So I'm using a function to linkify my plaint text
所以我使用一个函数来链接我的纯文本
private linkify(plainText): string{
let replacedText;
let replacePattern1;
let replacePattern2;
let replacePattern3;
//URLs starting with http://, https://, or ftp://
replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
replacedText = plainText.replace(replacePattern1, '<a href="" target="_blank"></a>');
//URLs starting with "www." (without // before it, or it'd re-link the ones done above).
replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
replacedText = replacedText.replace(replacePattern2, '<a href="http://" target="_blank"></a>');
//Change email addresses to mailto:: links.
replacePattern3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
replacedText = replacedText.replace(replacePattern3, '<a href="mailto:"></a>');
return replacedText;
}
But this returns a string with html encoding so if I use in with <p>{{example}}</p>
it will return full encoding (inlcuding anchor tags and html).
但这会返回一个带有 html 编码的字符串,因此如果我使用<p>{{example}}</p>
它,它将返回完整的编码(包括锚标记和 html)。
So now I use angular2 builtin html binding:
所以现在我使用 angular2 内置的 html 绑定:
This gives me the solution
这给了我解决方案