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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:48:49  来源:igfitidea点击:

Angular2 way of converting plain text to url (anchor links)

angulartypescriptangular2-routingangular2-templateangular2-directives

提问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

文字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?

我读了这个SO 答案,建议使用 3rd 方库,例如anchorme。有没有办法以 angular2 的方式做到这一点?

采纳答案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 targetattributes, 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

这给了我解决方案