Angular как использовать глобальный шаблон / область применения

#angular #templates #reusability

#angular #шаблоны #возможность повторного использования

Вопрос:

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

 <ng-template #menubutton let-link="link" let-icon="icon" let-text="text" ...>  
... does magic :)
</ng-template>
 

Я попытался извлечь эту часть

  1. в вводимый компонент общего меню
  2. добавление в app.component.html

но не работает и никаких ошибок.

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

Заранее спасибо,

Csaba

Комментарии:

1. app.component.html это не шаблон для всего приложения, это просто точка входа в приложение по умолчанию. Для вашего использования вы могли бы создать директиву, которая добавляет эти атрибуты, и добавить ее к любым необходимым элементам?

2. извините, я не понимаю, в чем дело, атрибуты исправлены, его данные поступают из json

3. Затем сделайте свой шаблон его собственным компонентом и передайте любые требуемые значения в качестве свойств @Input. Довольно сложно понять, каков ваш вариант использования здесь, без подробной информации о том, как вы в настоящее время используете этот шаблон, чтобы мы могли видеть, чего вы пытаетесь избежать.

4. Хорошо, для этого нужен собственный компонент, с другой стороны, это означает, что у нас не может быть глобальных шаблонов. (было бы намного проще поместить его в HTML-код области применения)

Ответ №1:

Я знаю, что это старый вопрос, но вот как я делаю это в своем проекте Angular в течение многих лет.

Нам нужна простая карта TemplateRef экземпляров:

 import { TemplateRef } from "@angular/core";

export class TemplateStore {
    private templates: Map<string, TemplateRef<any>> = new Map<string, TemplateRef<any>>();

    public add(key: string, template: TemplateRef<any>): void {
        // The argument validation is omitted for brevity

        this.templates.set(key, template);
    }

    public get(key: string): TemplateRef<any> {
        return this.templates.get(key);
    }
}
 

И директива, которая присваивает ключ шаблонам:

 import { Directive, Input, TemplateRef } from "@angular/core";
import { TemplateStore } from "./template-store";

@Directive({
    selector: "[appTemplateKey]"
})
export class TemplateKey {
    constructor(
        private readonly template: TemplateRef<any>,
        private readonly templateStore: TemplateStore
    ) { }

    @Input("appTemplateKey")
    public set key(value: string) {
        this.templateStore.add(value, this.template);
    }
}
 

Затем мы помещаем глобальные шаблоны в шаблон компонента приложения:

 <ng-template appTemplateKey="avatar" let-user>
    <a routerLink="/{{user.id}}" aria-hidden="true" tabindex="-1">
        <img [src]="user.pictureUrl" alt="" loading="lazy">
    </a>
</ng-template>
 

И использование:

 <ng-container *ngTemplateOutlet="templateStore.get('avatar'); context: {$implicit: currentUser}"></ng-container>
 

Недостаток здесь в том, что нам нужно вводить TemplateStore в каждый компонент, который его использует. Поскольку в моем проекте Angular все компоненты наследуют базовый класс, мы можем избежать внедрения, поместив в базовый класс метод, подобный этому:

 public template(key: string): TemplateRef<any> {
    return AppContext.current.templateStore.get(key);
}
 

Это AppContext.current глобальный объект, который содержит ссылку на TemplateStore . Таким образом, использование становится:

 <ng-container *ngTemplateOutlet="template('avatar'); context: {$implicit: currentUser}"></ng-container>
 

Комментарии:

1. Спасибо, сэр 🙂