2016-10-23 4 views
0

Я пишу Угловое 2 приложения и имеют компонент, который динамически визуализирует другие компоненты для представления, как описано на https://blog.thecodecampus.de/angular-2-dynamically-render-components/Сохранение родового объекта в частной собственности на классе

Этот процесс прекрасно работает, но вместо создания компонента и быстро уничтожить его из конструктора, я бы поставил эту логику в рамках другой функции класса, которая точно определяет, какой компонент должен быть записан на страницу на основе ввода. Существует функциональность для переключения, какой из этих дочерних компонентов показан, поэтому мне нужно иметь возможность хранить разрешенный компонент компонента, чтобы впоследствии я мог вызвать destroy(), и это приводит нас к проблеме.

Я хотел бы сохранить этот объект в классе в частной собственности, но я не могу понять, как его набирать. Вот что файл .d.ts должен описать функцию createComponent из которой объект изначально инстанцированный:

abstract createComponent<C>(componentFactory: ComponentFactory<C>, index?: number, injector?: Injector, projectableNodes?: any[][]): ComponentRef<C>; 

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

private _visibleElement: any; 

Теперь, конечно, я мог typeguard массив и сказать, что он может быть типа AppleComponent | BananaComponent | CherryComponent и т. Д., Но я бы хотел, чтобы это было более гибким и не нужно было поддерживать эти защитники каждый раз, когда я изменяю это, например.

private _visibleElement: ComponentRef<AppleComponent|BananaComponent|CherryComponent>; 

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

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

Спасибо!

ответ

1

Базовый интерфейс должен содержать что-то, если он пустой, то все будет принято:

interface MyComponent {} 

function create<T extends MyComponent>(comp: T) {} 

create(4); // no error 
create({ key: "value" }); // no error 

(code in playground)

Используя этот подход не требует, чтобы помнить, чтобы применить интерфейс на будущее классы, потому что безопасность типа просто напомнит вам.
После того, как у вас есть этот базовый интерфейс для всех компонентов, убедитесь, что у вас есть функции/типы, которые полагаются на это, таким образом, если вы представляете новый класс компонентов и не реализуете BaseComponent, тогда компилятор будет вызывать ошибки при попытке использовать его.
Например, вы можете иметь:

type MyRef<T extends BaseComponent> = ComponentRef<T>; 

И затем использовать его везде:

abstract createComponent<C extends BaseComponent>(componentFactory: ComponentFactory<C>, index?: number, injector?: Injector, projectableNodes?: any[][]): MyRef<C>; 
+0

Имеет смысл, спасибо. – Xaniff

Смежные вопросы