Angular2 将纯文本转换为 url(锚链接)的方法
Angular2 way of converting plain text to url (anchor links)
我有时有一个组件可以接收这样的文本:
text www.website.com
但如果它是 link,我想将其转换为 url。像这样。
text www.website.com
我读了这个SO answer that suggests using 3rd party libs such as anchorme。有没有办法用 angular2 的方式来做?
好的,我就是这样做的留下答案希望它能帮助别人:
所以我正在使用一个函数来链接我的纯文本
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;
}
但是这个 return 是一个带有 html 编码的字符串,所以如果我使用 in with <p>{{example}}</p>
它将 return 完整编码(包括锚标记和 html).
所以现在我使用 angular2 内置 html 绑定:
这给了我解决方案
好吧,要制作一个管道,您需要制作一个由
组成的管道组件
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;
}
}
然后像导入指令一样导入它,将它传递给
pipes: [LinkifyPipe]
并像这样插值
{{url | linkify}}
你应该这样使用这个管道:
<div [innerHtml]="note.title | linkify"></div>
使用简单的正则表达式修改 HTML 内容有很多问题。
这是一种使用 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;
}
}
注意:如果您需要指定 target
属性,请添加例如。 {target: '_system'}
作为 linkifyStr
.
的第二个参数
你应该检查 angular-linky https://github.com/dzonatan/angular-linky
<span [innerHTML]="yourText | linky"></span>
我已经搜索了解决方案,但无济于事。我需要扩展处理 Angular 路由 [routerLink] 和 [innerHTML] 外部链接的要求,而不需要第三方库。
我的解决方案(总结):
Angular 2,Angular 5 - 用户点击 events/event 处理动态 [innerHTML] 生成的内容,使用管道和指令生成并将纯文本转换为点击 url,例如 #hashtags , @Handle, @Mention, #routerLink #href 和 #mailto 等
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'
];
}
}
指令
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 });
}
}
}
管道
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;
}
}
我有时有一个组件可以接收这样的文本:
text www.website.com
但如果它是 link,我想将其转换为 url。像这样。
text www.website.com
我读了这个SO answer that suggests using 3rd party libs such as anchorme。有没有办法用 angular2 的方式来做?
好的,我就是这样做的留下答案希望它能帮助别人:
所以我正在使用一个函数来链接我的纯文本
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;
}
但是这个 return 是一个带有 html 编码的字符串,所以如果我使用 in with <p>{{example}}</p>
它将 return 完整编码(包括锚标记和 html).
所以现在我使用 angular2 内置 html 绑定:
这给了我解决方案
好吧,要制作一个管道,您需要制作一个由
组成的管道组件 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;
}
}
然后像导入指令一样导入它,将它传递给
pipes: [LinkifyPipe]
并像这样插值
{{url | linkify}}
你应该这样使用这个管道:
<div [innerHtml]="note.title | linkify"></div>
使用简单的正则表达式修改 HTML 内容有很多问题。
这是一种使用 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;
}
}
注意:如果您需要指定 target
属性,请添加例如。 {target: '_system'}
作为 linkifyStr
.
你应该检查 angular-linky https://github.com/dzonatan/angular-linky
<span [innerHTML]="yourText | linky"></span>
我已经搜索了解决方案,但无济于事。我需要扩展处理 Angular 路由 [routerLink] 和 [innerHTML] 外部链接的要求,而不需要第三方库。
我的解决方案(总结):
Angular 2,Angular 5 - 用户点击 events/event 处理动态 [innerHTML] 生成的内容,使用管道和指令生成并将纯文本转换为点击 url,例如 #hashtags , @Handle, @Mention, #routerLink #href 和 #mailto 等
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'
];
}
}
指令
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 });
}
}
}
管道
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;
}
}