Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular2将纯文本转换为url的方式(锚链接)_Angular_Typescript_Angular2 Routing_Angular2 Template_Angular2 Directives - Fatal编程技术网

Angular2将纯文本转换为url的方式(锚链接)

Angular2将纯文本转换为url的方式(锚链接),angular,typescript,angular2-routing,angular2-template,angular2-directives,Angular,Typescript,Angular2 Routing,Angular2 Template,Angular2 Directives,我有时有一个组件可以接收如下文本: 文本www.website.com 但是如果它是一个链接,我想把它转换成一个url。像这样 正文 我读到这篇文章,建议使用第三方LIB,例如。有什么方法可以用angular2的方式做吗?好的,我就是这样做的,希望它能帮助其他人: 所以我用一个函数来链接我的明文 private linkify(plainText): string{ let replacedText; let replacePattern1; let replacePat

我有时有一个组件可以接收如下文本:

文本www.website.com

但是如果它是一个链接,我想把它转换成一个url。像这样

正文


我读到这篇文章,建议使用第三方LIB,例如。有什么方法可以用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="$1" target="_blank">$1</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, '$1<a href="http://$2" target="_blank">$2</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:$1">$1</a>');

    return replacedText;
}
private linkify(纯文本):字符串{
让替换文本;
让我们换一个模式1;
让我们来看一看第二种模式;
让我们来看看第三种模式;
//以http://、https://或ftp开头的URL://
replacePattern1=/(\b(https?| ftp):\/\/[-A-Z0-9+&@#\/%?=~~|!:,.;]*[-A-Z0-9+&@#\/%=~|]/gim;
replacedText=纯文本。replace(replacePattern1',);
//以“www.”开头的URL(前面没有//或它会重新链接上面的内容)。
replacePattern2=/(^.[^\/])(www\.[\S]+(\b\$)/gim;
replacedText=replacedText.replace(replacePattern2,$1');
//将电子邮件地址更改为mailto::links。
替换模式3=/([a-zA-Z0-9\-\\\\\\\\.])+@[a-zA-Z\\\\\\+?(\.[a-zA-Z]{2,6})+/gim;
replacedText=replacedText.replace(replacePattern3');
返回replacedText;
}
但是这会返回一个带有html编码的字符串,所以如果我在with
{{example}

中使用,它将返回完整编码(包括锚定标记和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="$1" target="_blank">$1</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, '$1<a href="http://$2" target="_blank">$2</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:$1">$1</a>');

        return replacedText;
       }
    }
然后像这样插值

{{url | linkify}}

应按以下方式使用此管道:


使用简单正则表达式修改HTML内容时存在许多问题

下面是一种使用该模块的方法,您需要
npm安装该模块
。请注意,输入被视为纯文本,而输出是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:''u system'}
作为第二个参数添加到
linkifyStr
中,您应该检查角度链接


我已经搜索了一个解决方案,但没有结果。我需要扩展使用[innerHTML]处理角度路由[routerLink]和外部链接的需求,而不需要第三方LIB

我的解决方案(摘要):

Angular 2、Angular 5-用户点击事件/事件处理动态[innerHTML]生成的内容,使用管道和指令生成并转换纯文本以点击URL,例如#hashtags、@Handle、@title、#routerLink#href和#mailto等

Plunker演示:

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($1, $2, $3) {
                        let url: any = $1;
                        let urlClean: any = url.replace("" + $3 + "://", "");

                        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/$2\" class=\"hashtag-link\">$1$2</a>");
        }

        // Find/Replace #hashtags in text
        if (text.match(this.mentions)) {
            text = text.replace(this.mentions, "<a href=\"/search/handle/$2\" class=\"handle-link\">$1$2</a>");
        }

        // Find/Replace email addresses in text
        if (text.match(this.emails)) {
                text = text.replace(this.emails, "<a href=\"mailto:$1\">$1</a>");
        }

        return text;
    }  
}
export类ParseUrl实现PipeTransform{
URL:any=/(\b(https?| http | ftp | ftps | https | rtsp | rtsp):\/\/[A-Z0-9+&@\/%?=~|!:,.-]*[-A-Z0-9+&\/%=~|]/gim;//在文本中查找/替换URL
hashtags:any=/(^ |\s)(#[a-z\d][\w-]*)/ig;//在文本中查找/替换#hashtags
提及:any=/(^ |\s)(@[a-z\d][\w-]*)/ig;//在文本中查找/替换@Handle/提及
电子邮件:any=/(\S+@\S+\.\S+)/gim;//在文本中查找/替换电子邮件地址
转换(文本:字符串){
返回此.parseUrl(文本);
}
专用解析URL(文本:字符串){
//在文本中查找/替换URL
if(text.match(this.url)){
text=text.replace(this.url,函数replacer($1,$2,$3){
让url:any=$1;
让urlClean:any=url.replace(“+$3+”:/”,“”);
返回“”;
});
}
//在文本中查找/替换@Handle/提及
if(text.match(this.hashtags)){
text=text.replace(this.hashtags,“”);
}
//查找/替换文本中的哈希标记
if(text.match(this.references)){
text=text.replace(this.references,“”);
}
//在文本中查找/替换电子邮件地址
if(text.match(this.email)){
text=text.replace(this.emails,“”);
}
返回文本;
}  
}

这有什么问题吗?有一些方法可以在渲染后动态注入可观察的DOM元素,但它不安全且沉重。你最好的办法是用烟斗。我知道它们可能很吓人,但如果你在插值上使用管道,它会对其进行操作,并根据你的意愿将其吐出。如果你感兴趣的话,请告诉我,我会在答案框中列出一个例子,我们可以解决这个问题。函数和管道本质上是一样的。管道将是模块化的和更干净的,但是如果您想将其作为一个答案,欢迎您,我可以接受您的答案,一旦它的workingIt返回“”作为一个字符串,与dom元素不一样。有一个JavaScriptDOMParser可以将HTML转换为JavaScript。我最近遇到了这个问题,您不能使用Strings欺骗dom元素。我认为我们需要将结果绑定到innerHtml。如果我们使用的是Angular2```````在linkify()函数的开头,添加:
plainText=plainText.replace(“,”)
停止控制台中的注射尝试和投诉。然后使用Amr提到的bind to innerHTML感谢您提供了这个很棒的库,但是在typescript中不能包含'linkifyjs/string',我找不到任何typescript对库的支持。我认为如果我们使用Angular2````````````,我们需要将结果绑定到innerHTML,您可以像这样导入库:
var linkifyString=require('linkifyjs/string')
并以相同的方式使用,没有任何typescript支持。起初它对我不起作用,我一直收到
string_1。默认值不是一个函数
错误。最终我发现将import语句从'linkifyjs/string'更改为
import*as linkifyString解决了这个问题。
最适合Angular。
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($1, $2, $3) {
                        let url: any = $1;
                        let urlClean: any = url.replace("" + $3 + "://", "");

                        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/$2\" class=\"hashtag-link\">$1$2</a>");
        }

        // Find/Replace #hashtags in text
        if (text.match(this.mentions)) {
            text = text.replace(this.mentions, "<a href=\"/search/handle/$2\" class=\"handle-link\">$1$2</a>");
        }

        // Find/Replace email addresses in text
        if (text.match(this.emails)) {
                text = text.replace(this.emails, "<a href=\"mailto:$1\">$1</a>");
        }

        return text;
    }  
}