разрешить AOT-совместимый способ предоставления пользовательской замены templateUrl для компонента Angular - PullRequest
1 голос
/ 12 января 2020

Я ищу вариант для создания библиотеки Angular, содержащей компоненты, с возможностью их настройки с пользовательскими templateUrl s. Идея состоит в том, чтобы настроить шаблоны в библиотеке перед созданием приложения, поэтому я хотел бы иметь возможность полностью использовать AOT - в идеале stati c. Я могу представить себе некоторые выделенные логи c например. пользовательский декоратор, который будет использоваться на месте или вместе с @Component для достижения sh моей потребности.

При поиске настройки шаблонов большая часть информации, которую я нашел, относится к настройке времени выполнения, которая не нужна в мое дело. Буду признателен за любые идеи и предложения.

После некоторого исследования я обнаружил, что мне нужно создать библиотеку с

"angularCompilerOptions": {
  "enableResourceInlining": false
}

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

ОБНОВЛЕНИЕ : один совет, который я Выяснилось, что нужно ретранслировать на ivy и использовать компонент более высокого порядка - это был бы отличный вариант, поскольку я использую Ioni c Поддержка ivy все еще в процессе.

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

<ng-container *ngTemplateOutlet="template">
</ng-container>

<ng-template #default>
  default content template
</ng-template>
@Component({
    selector: 'original-component',
    templateUrl: './original-component.html',
    styleUrls: ['original-component.scss'],
})
export class OriginalComponent implements AfterViewInit {
    @ViewChild('default', {read: TemplateRef, static: false}) defaultTemplate: TemplateRef<any>;
    template: TemplateRef<any>;

    constructor(
        @Optional() @Inject(TEMPLATE_OVERRIDE_KEY) public readonly templateOverrideKey: string,
        private templateRegistry: TemplateRegistry) {}

    ngAfterViewInit(): void {
        if (this.templateRegistry.get(this.templateOverrideKey)) {
            this.template = this.templateRegistry.get(this.templateOverrideKey);
        }
        if (!this.template) {
            this.template = this.defaultTemplate;
        }
    }
}

, затем таким же образом определите пользовательский шаблон и используйте службу TemplateRegistry для передачи это как переопределение.

недостатки этого решения

  • это опция Dynami c, которая выполняется во время выполнения, и я бы предпочел просто "заменить" шаблон перед сборкой как только одна версия шаблона будет использоваться в конкретном приложении
  • Мне нужно где-то явно использовать пользовательский компонент (например, в компоненте приложения), чтобы он был инициализирован и только тогда имел Для TemplateRef
  • необходимо использовать let-ctx и получить доступ ко всем исходным данным через ctx.myVar, так как ng-template работает прямо сейчас.

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

...