Перемещение дерева компонентов с помощью DI
Прикладные компоненты часто должны обмениваться информацией. Часто вы можете использовать слабосвязанные методы для обмена информацией, такие как привязка данных и обмен услугами, но иногда имеет смысл, чтобы один компонент имел прямую ссылку на другой компонент. Например, вам нужна прямая ссылка для доступа к значениям или вызову методов этого компонента.
Получение ссылки на компонент немного сложнее в Angular. Сами угловые компоненты не имеют дерева, которое вы можете просматривать или перемещать программно. Родительско-дочерние отношения являются косвенными и устанавливаются через объекты представления компонентов.
Каждый компонент имеет представление хоста и может иметь дополнительные встроенные представления. Встроенный вид в компоненте A - это хост-вид компонента B, который, в свою очередь, может иметь встроенный вид. Это означает, что существует иерархия представления для каждого компонента, корневым представлением которого является этот компонент.
Найти родительский компонент известного типа
Вы используете инъекцию стандартного класса, чтобы получить родительский компонент, тип которого вы знаете.
В следующем примере родительский VitaComponent имеет несколько дочерних элементов, включая AryanComponent:
Код TypeScript:
@Component({
selector: 'vita',
template: `
<div class="a">
<h3>{{name}}</h3>
<aryan></aryan>
<craig></craig>
<carol></carol>
</div>`,
})
export class VitaComponent extends Base
{
name ='Vita';
}
Демонстрация в реальном времени:
См. Pen parent-finder.ts (VitaComponent v.1) по w3resource ( @ w3resource ) в CodePen .
Ариан сообщает, имеет ли он доступ к Vita после введения компонента Vita в его конструктор:
Код TypeScript:
@Component({
selector: 'aryan',
template: `
<div class="a">
<h3>Aryan</h3>
{{vita ? 'Found' : 'Did not find'}} Vita via the component class.<br>
</div>
})
export class AryanComponent {
constructor( @Optional() public vita: VitaComponent ) { }
}
Демонстрация в реальном времени:
См. Pen parent-finder.ts (AryanComponent) от w3resource ( @ w3resource ) в CodePen .
Невозможно найти родителя по его базовому классу
Что если вы не знаете конкретный класс родительского компонента?
Повторно используемый компонент может быть дочерним для нескольких компонентов. Представьте себе компонент для отображения последних новостей о финансовом инструменте. По деловым соображениям этот новостной компонент часто совершает звонки непосредственно в свой родительский инструмент, изменяя потоки рыночных данных.
Приложение, вероятно, определяет более десятка компонентов финансовых инструментов. Если вам повезет, все они реализуют один и тот же базовый класс, API которого понимает ваш NewsComponent.
Оглядываясь назад, вы видите, что компонент Vita расширяет (наследует) класс с именем Base.
export class VitaComponent extends Base
CraigComponent пытается внедрить Base в свой параметр конструктора vita и сообщает, если это удалось.
Код TypeScript:
@Component({
selector: 'craig',
template: `
<div class="c">
<h3>Craig</h3>
{{alex ? 'Found' : 'Did not find'}} Vita via the base class.
</div>`
})
export class CraigComponent {
constructor( @Optional() public vita: Base ) { }
}
Демонстрация в реальном времени:
См. Pen parent-finder.ts (CraigComponent) от w3resource ( @ w3resource ) в CodePen .
Найти родителя по интерфейсу класса
Вы можете найти родительский компонент с интерфейсом класса.
Родитель должен сотрудничать, предоставляя себе псевдоним в имени токена интерфейса класса.
Напомним, что Angular всегда добавляет экземпляр компонента в свой собственный инжектор; вот почему вы могли бы ввести Vita в Кэти раньше.
Напишите провайдера псевдонимов - литерал обеспечения объекта с определением useExisting, - который создает альтернативный способ внедрения того же экземпляра компонента и добавления этого провайдера в массив провайдера метаданных @Component () для VitaComponent.
providers: [{ provide: Parent, useExisting: forwardRef(() => VitaComponent) }],
Родитель - это токен интерфейса класса провайдера. ForwardRef ломает круговую ссылку, которую вы только что создали, когда VitaComponent ссылается на себя.
Кэрол, третий из дочерних компонентов Vita, вставляет родителя в его родительский параметр, так же, как вы делали это раньше. Ниже представлен класс CarolComponent
export class CarolComponent {
name ='Carol';
constructor( @Optional() public parent: Parent ) { }
}
Найдите родителя в дереве с помощью @SkipSelf ()
Представьте себе одну ветвь иерархии компонентов: Алиса -> Барри -> Кэрол. И Алиса, и Барри реализуют интерфейс класса «Родитель».
Барри это проблема. Он должен связаться со своим родителем, Алисой, а также быть родителем для Кэрол. Это означает, что он должен внедрить интерфейс класса Parent, чтобы получить Алису, и предоставить Parent, чтобы удовлетворить Кэрол.
Код TypeScript:
const templateB = `
<div class="b">
<div>
<h3>{{name}}</h3>
<p>My parent is {{parent?.name}}</p>
</div>
<carol></carol>
<chris></chris>
</div>`;
@Component({
selector: 'barry',
template: templateB,
providers: [{ provide: Parent, useExisting: forwardRef(() => BarryComponent) }]
})
export class BarryComponent implements Parent {
name ='Barry';
constructor( @SkipSelf() @Optional() public parent: Parent ) { }
}
Демонстрация в реальном времени:
См. Pen parent-finder.ts (BarryComponent) от w3resource ( @ w3resource ) в CodePen .
Предыдущий: Инъекторы иерархической зависимости
Далее: Маршрутизация и навигация
Новый контент: Composer: менеджер зависимостей для PHP , R программирования