如何在 angular 5 中将指令应用于 innerHtml 中的元素?
How to apply a directive to elements in innerHtml in angular 5?
这适用于 Angular 5 / Ionic 3 应用程序。
我有一个 div,我在其中显示用户从富文本编辑器生成的 html:
<div [innerHtml]='text'></div>
此数据可以包括 <a href>
个链接,我需要为其捕获点击事件以强制在系统的默认浏览器中打开。
我制定了一个指令,它可以完美地用于静态内容,但不会影响 innerHtml 元素内的任何内容。
import { Directive, Input, HostListener } from "@angular/core";
import { InAppBrowser } from "@ionic-native/in-app-browser";
@Directive({
selector : '[href]'
})
export class PreventLink {
@Input() href;
constructor( private iab: InAppBrowser ) {};
@HostListener('click', ['$event'])
public onClick( event: Event ) {
if( event && this.href ) {
if( this.href.length > 0 ){
this.iab.create( this.href, '_system' );
}
event.preventDefault();
return false;
}
};
};
任何实现我需要的想法都将不胜感激。
如果有人想知道如何做,我会post在这里我的 hacky 解决方案。我仍然希望有更好的 "angular" 解决方案来实现这一目标。
首先,我们需要在 index.html 中准备一个基本的 javascript 代码片段,以找出锚点何时被点击。将其放在该部分的末尾。
<script>
document.onclick = function (e){
e = e || window.event || {};
var element = e.target || e.srcElement;
if (element && element.tagName == 'A') {
handleAClick( element.href );
e.preventDefault();
return false;
}
};
function handleAClick(){}; //Just a placeholder until the angular app is ready
</script>
然后在 app.component.ts 中,我将用真正的交易覆盖 handleAClick 函数:
import { Component, OnInit, ViewChild } from '@angular/core';
import { InAppBrowser } from '@ionic-native/in-app-browser';
import { Platform } from 'ionic-angular';
@Component({
templateUrl: 'app.html'
})
export class MySuperApp implements OnInit {
constructor( private platform: Platform, private iab: InAppBrowser ){};
ngOnInit() {
this.platform.ready().then( () => {
let win = (<any>window);
win.handleAClick = ( url: string ) => {
this.handleAClick( url );
};
});
};
private handleAClick( href: string ) {
if( href && href.length > 0 ) {
this.iab.create( href, '_system' );
}
};
};
这个 post 已经很老了,但是如果其他人遇到这个问题,我使用几乎相同的自定义指令解决了它,确认此设置对我有用 angular 9 / ionic 5.
import { Directive, HostListener } from '@angular/core';
/**
* Custom directive so that we can listen for clicks (or taps) on the event detail page.
* When the user clicks on an embeded link it will be opened by the browser service and now what ever target
* the link was written for.
* Since we dont control the content of the event feed descriptions this is the only way we can control
* what happens when they include a link and the user opens it.
*/
@Directive({
selector: '[linkInterceptor]',
})
export class LinkIntereptorDirective {
@HostListener('click', ['$event']) onClick(event: any) {
this.clickJack(event);
}
@HostListener('tap', ['$event']) onTap(event: any) {
this.clickJack(event);
}
private clickJack(event) {
event.preventDefault();
if (event.target.tagName.toLowerCase() === 'a') {
this.open(event.target.href);
}
}
private async open(href) {
// here you can handle how you want to open the url.
}
constructor() { }
}
模板:
<div *ngIf="content.length" class="ion-padding-horizontal" tappable linkInterceptor [innerHtml]="getHtml()"></div>
组件:
/**
* For somereason on ionic when you use the pipe syntax to sanitize
* html it makes the content block not clickable. So this fixes that so we can register our custom link interceptor directive.
*/
getHtml(): SafeHtml {
return this.domSanitizer.sanitize(SecurityContext.HTML, htmlContent);
}
这适用于 Angular 5 / Ionic 3 应用程序。 我有一个 div,我在其中显示用户从富文本编辑器生成的 html:
<div [innerHtml]='text'></div>
此数据可以包括 <a href>
个链接,我需要为其捕获点击事件以强制在系统的默认浏览器中打开。
我制定了一个指令,它可以完美地用于静态内容,但不会影响 innerHtml 元素内的任何内容。
import { Directive, Input, HostListener } from "@angular/core";
import { InAppBrowser } from "@ionic-native/in-app-browser";
@Directive({
selector : '[href]'
})
export class PreventLink {
@Input() href;
constructor( private iab: InAppBrowser ) {};
@HostListener('click', ['$event'])
public onClick( event: Event ) {
if( event && this.href ) {
if( this.href.length > 0 ){
this.iab.create( this.href, '_system' );
}
event.preventDefault();
return false;
}
};
};
任何实现我需要的想法都将不胜感激。
如果有人想知道如何做,我会post在这里我的 hacky 解决方案。我仍然希望有更好的 "angular" 解决方案来实现这一目标。
首先,我们需要在 index.html 中准备一个基本的 javascript 代码片段,以找出锚点何时被点击。将其放在该部分的末尾。
<script>
document.onclick = function (e){
e = e || window.event || {};
var element = e.target || e.srcElement;
if (element && element.tagName == 'A') {
handleAClick( element.href );
e.preventDefault();
return false;
}
};
function handleAClick(){}; //Just a placeholder until the angular app is ready
</script>
然后在 app.component.ts 中,我将用真正的交易覆盖 handleAClick 函数:
import { Component, OnInit, ViewChild } from '@angular/core';
import { InAppBrowser } from '@ionic-native/in-app-browser';
import { Platform } from 'ionic-angular';
@Component({
templateUrl: 'app.html'
})
export class MySuperApp implements OnInit {
constructor( private platform: Platform, private iab: InAppBrowser ){};
ngOnInit() {
this.platform.ready().then( () => {
let win = (<any>window);
win.handleAClick = ( url: string ) => {
this.handleAClick( url );
};
});
};
private handleAClick( href: string ) {
if( href && href.length > 0 ) {
this.iab.create( href, '_system' );
}
};
};
这个 post 已经很老了,但是如果其他人遇到这个问题,我使用几乎相同的自定义指令解决了它,确认此设置对我有用 angular 9 / ionic 5.
import { Directive, HostListener } from '@angular/core';
/**
* Custom directive so that we can listen for clicks (or taps) on the event detail page.
* When the user clicks on an embeded link it will be opened by the browser service and now what ever target
* the link was written for.
* Since we dont control the content of the event feed descriptions this is the only way we can control
* what happens when they include a link and the user opens it.
*/
@Directive({
selector: '[linkInterceptor]',
})
export class LinkIntereptorDirective {
@HostListener('click', ['$event']) onClick(event: any) {
this.clickJack(event);
}
@HostListener('tap', ['$event']) onTap(event: any) {
this.clickJack(event);
}
private clickJack(event) {
event.preventDefault();
if (event.target.tagName.toLowerCase() === 'a') {
this.open(event.target.href);
}
}
private async open(href) {
// here you can handle how you want to open the url.
}
constructor() { }
}
模板:
<div *ngIf="content.length" class="ion-padding-horizontal" tappable linkInterceptor [innerHtml]="getHtml()"></div>
组件:
/**
* For somereason on ionic when you use the pipe syntax to sanitize
* html it makes the content block not clickable. So this fixes that so we can register our custom link interceptor directive.
*/
getHtml(): SafeHtml {
return this.domSanitizer.sanitize(SecurityContext.HTML, htmlContent);
}