Angular Directive - Как добавить якорь и установить routerlink для элемента dom - PullRequest
0 голосов
/ 11 октября 2019

Я хочу создать структурную директиву, которая превращает следующее

<any-dom-element anchorDirective="baseRoute">{{itemId}}</any-dom-element>

в

<any-dom-element>
    <a [routerLink]="[baseRoute, itemId]">{{itemId}}</a>
</any-dom-element>

sofar У меня есть

import { Directive, TemplateRef, ViewContainerRef, Input } from '@angular/core';

@Directive({ selector: '[anchorDirective]' })
export class AnchorDirective {
    @Input() set sbAnchor(baseRoute: string) {
        const a = document.createElement('a');
        a.href = baseRoute;
        // <------ How to insert the anchor, so that it will work with angulars router?
        this.viewContainer.createEmbeddedView(this.templateRef)
    }
    constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) {}
}

Так что мои вопросы

  1. Как вставить созданный якорь
  2. Как заставить созданный якорь работать с маршрутизатором angulars?

1 Ответ

1 голос
/ 11 октября 2019

Краткий ответ на два ваших конкретных вопроса: это невозможно.

Начиная с Angular 8, невозможно динамически добавлять директиву (в данном случае routerLink) к любому элементу. В репозитории Angular есть открытый вопрос о возможности применения директивы к элементу узла компонента. Хотя этот вопрос не совсем то, что вы ищете, они разделяют некоторую общность. Если бы было возможно динамически добавить директиву к любому элементу, то также было бы возможно применить ее к элементу хоста компонента.

Если вас не интересуют конкретные детали реализации вашей искомой функции, тогданиже предложение для альтернативного подхода.

Я предлагаю реализовать ваш якорь в качестве компонента, который имеет селектор атрибута вместо структурной директивы:

@Component({
  selector: '[anchor]', // <-- The component selector can be an attribute, it doesn't have to be an element tag.
  templateUrl: './anchor.component.html',
  styleUrls: ['./anchor.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class AnchorComponent implements OnInit {}

При таком подходе вы теперь можете заполнять шаблон компонента любым угловым качеством:)

Компонент может использоваться следующим образом:

<div [anchor]="baseRoute"></div>

или

<h1 [anchor]="baseRoute"></h1>

или

<p [anchor]="baseRoute"></p>

и т.д ...

Этот подход не работает, однако, если вам нужно иметь возможность применить компонент к другому компоненту. Пример:

<some-angular-component [anchor]="baseRoute"></some-angular-component>

Если вы попытаетесь это сделать, вы получите следующую ошибку консоли времени выполнения:

Template parse errors:
More than one component matched on this element.
...