У меня есть cmd, где я получаю содержимое страницы с сервера. Тогда контент может включать HTML и ссылки. Проблема в том, что когда я показываю эти данные, ссылки не работают. При просмотре источника страницы выясняется, что "routerLink" преобразуется в "соединение с маршрутизатором" и почему он, вероятно, не работает. Вот мой код:
Мой класс, обратите внимание, что routerLink находится в camelcase здесь:
export class TwoComponent implements OnInit {
data = '<a routerLink="/one">ONE</a>'; //this will actually come from backend server
constructor() { }
ngOnInit() {}
}
И мой html:
<div [innerHTML]="data | bypassSecurity"></div>
И когда я загружаю эту страницу и смотрю на источник, routerLink теперь находится в нижнем регистре:
<a routerlink="/one">ONE</a>
Сначала я подумал, что это протокол bypassSecurity, который отвечает, но я проверил вывод трубы, и routerLink все еще был в верблюжьем корпусе. Так кажется, что это происходит где-то в другом месте. На всякий случай, здесь тоже моя труба bypassSecurity:
export class BypassSecurityPipe implements PipeTransform {
constructor(private sanitized: DomSanitizer) {}
transform(value): any {
return this.sanitized.bypassSecurityTrustHtml(value);
}
}
Любые советы о том, где и почему происходит это преобразование в нижнем регистре, будут оценены :)
Решение jcdsr мне очень помогло. Я получил эту работу, используя ее с DomSanitizer
.
Вот как я это сделал:
import { Directive, ElementRef, HostListener } from '@angular/core';
import { Router } from '@angular/router';
@Directive({
selector: '[routeTransformer]'
})
export class RouteTransformerDirective {
constructor(private el: ElementRef, private router: Router) { }
@HostListener('click', ['$event'])
public onClick(event) {
if (event.target.tagName === 'A') {
this.router.navigate([event.target.getAttribute('href')]);
event.preventDefault();
} else {
return;
}
}
};
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
public html: SafeHtml;
constructor(private sanitizer: DomSanitizer) {
this.html = sanitizer.bypassSecurityTrustHtml('<a href="/something">Link</a>');
}
<div [innerHtml]="html" routeTransformer></div>
Это мое решение, вам нужно только использовать атрибуты html5.
по шаблону:
<div [innerHtml]="testHtml" (click)="getRoute($event)"></div>
в компоненте:
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls:['./app.component.css'],
})
export class oneComponent implements OnInit {
testHtml: any;
constructor( private router: Router,) {}
this.testHtml='
<br>
------- <span data-link="/page 1">Page 1</span> -------
<br>
------- <a data-link="/page 2">Page 2</a> -------
<br>
text -- ';
getRoute(event) {
var goRoute = event.target.getAttribute('data-link')
alert(goRoute);
this.router.navigate([goRoute]);
}
}
или как директива,
import { Directive, ElementRef, HostListener } from '@angular/core';
import { Router } from '@angular/router';
@Directive({
selector: '[routeDirective]'
})
export class routeDirective {
constructor(private el: ElementRef, private router: Router) { }
@HostListener('click', ['$event.target']) onClick($event){
console.info('clicked: ' + $event.getAttribute('data-link'));
var goRoute = $event.getAttribute('data-link');
this.router.navigate([goRoute]);
}
}
по шаблону в качестве директивы:
<div [innerHtml]="testHtml" routeDirective></div>
недостатки:
Поисковые системы отлично с "тегом" без атрибутов. Они не будут видеть это как ссылку, и они не будут пытаться передать сок ссылки на него - SEO.
Я нашел очень удобное решение для использования routerLink
внутри innerHTML
с использованием Angular Elements:
ng add @angular/elements
<a [routerLink]="href"><ng-content></ng-content></a>
<a>
как это<your-custom-element href="/your/link">THE LINK TITLE</your-custom-element>
Таким образом, вы имеете полный контроль над связью маршрутизатора и все еще используете innerHTML с контентом из внешнего (доверенного) источника.
Вы пробовали другие синтаксисы routerLink, чтобы увидеть, будет ли интерпретатор действовать по-другому?
<a [routerLink]="javascript code here that return a string or an array"> </a>
вместо вашего
<a routerlink="/one">ONE</a>
Вы должны вернуть <a href="/one">ONE</a>
вместо <a routerLink="/one">ONE</a>
с сервера.
Я пробовал это, и это работает на меня.
Я действительно не знаю, чего вы пытаетесь достичь здесь, но вы не должны получать весь фрагмент кода из бэкэнда. Вместо этого просто получите значение "один" и используйте интерполяцию на стороне клиента для генерации <a routerLink="/one">ONE</a>
:
В шаблоне:
<a routerLink="value">{{value}}</a>