Рассмотрим следующий пример:
@Directive({
selector: '[testActiveTab]'
})
export class ActiveTabDirective {
@Input('testActiveTab') active: boolean = true;
constructor(
private parent: TabbedContainerComponent, // <--
private child: TabComponent // <--
) {
}
// ...
}
Использование в шаблоне:
<test-tabbed-container>
<test-tab>
<!-- ... -->
</test-tab>
<test-tab testActiveTab>
<!-- ... -->
</test-tab>
</test-tabbed-container>
Как вы, наверное, уже догадались, эта директива используется для отметки активной вкладки внутри компонента с вкладками.
Возможная проблема заключается в том, что каждый раз, когда создается экземпляр ActiveTabDirective
, инжектор заново заново ActiveTabDirective
parent
и child
свойства, а это означает, что если в контейнере есть n
вкладок, произойдет инициализация 2 * n
.
Вопрос:
Является ли зависимость инъекцией дорогостоящей операции в Angular2+? Или это просто передача ссылки, поэтому она дешевая?
"Расценка" здесь описывает способ работы иерархической инъекции зависимостей в угловом выражении, а результат - результат.
DI не может создавать и внедрять компоненты, которые не связаны с скомпилированными элементами.
Провайдеры являются одноточечными (в объеме текущего инжектора). Если поставщик не определен в текущем инжекторе, но был создан в родительском инжекторе, в него вводится существующий экземпляр поставщика.
Хотя классы Injectable
, Directive
и Component
являются инъецируемыми, Angular четко различает директивы/компоненты (определенные в declarations
) от обычных поставщиков (определенных в providers
), и они ведут себя по-разному. Директивы/компоненты создаются компилятором, поэтому дополнительный экземпляр не может быть случайно введен.
constructor(
private parent: TabbedContainerComponent,
private child: TabComponent
) {}
будет вводить существующие экземпляры компонентов или бросать, если их нет. Где "ребенок" на самом деле "я", потому что дети еще не были скомпилированы и должны быть получены с помощью ViewChild
или ContentChild
если это необходимо.