У меня есть родительский компонент, который отправляется на сервер и получает объект:
// parent component
@Component({
selector : 'node-display',
template : `
<router-outlet [node]="node"></router-outlet>
`
})
export class NodeDisplayComponent implements OnInit {
node: Node;
ngOnInit(): void {
this.nodeService.getNode(path)
.subscribe(
node => {
this.node = node;
},
err => {
console.log(err);
}
);
}
И в одном из нескольких детских дисплеев:
export class ChildDisplay implements OnInit{
@Input()
node: Node;
ngOnInit(): void {
console.log(this.node);
}
}
Не похоже, что я могу просто ввести данные в файл router-outlet
. Похоже, я получаю ошибку в веб-консоли:
Can't bind to 'node' since it isn't a known property of 'router-outlet'.
В этом есть смысл, но как бы я сделал следующее:
- Получить данные "узла" с сервера из родительского компонента?
- Передать данные, полученные с сервера, в дочерний маршрутизатор-выход?
Это не похоже на то, чтобы router-outlets
работать так же.
node
где это как тип,string
но похоже, что это не работает, или я делаю что-то не такElementRef
событие из розетки маршрутизатора, чтобы использовать его для установки идентификатора, но я не знаю наизусть, если и как это сделать (только на моем телефоне)Ответ Гюнтерса великолепен, я просто хочу указать другой способ без использования Observables.
Здесь мы должны помнить, что эти объекты передаются по ссылке, поэтому, если вы хотите поработать с объектом в дочернем объекте и не влиять на родительский объект, я бы предложил использовать решение Гюнтера. Но если это не имеет значения или действительно желаемое поведение , я бы предложил следующее.
@Injectable() export class SharedService { sharedNode = { // properties }; }
В родительском элементе вы можете присвоить значение:
this.sharedService.sharedNode = this.node;
И в ваших дочерних элементах (И родительском) вставьте общий сервис в свой конструктор. Не забудьте предоставить услугу в массиве поставщиков на уровне модуля, если вы хотите, чтобы одноэлементная служба использовалась для всех компонентов в этом модуле. В качестве альтернативы просто добавьте службу в массив поставщиков только в родительском элементе , тогда родительский и дочерний элементы будут использовать один и тот же экземпляр службы.
node: Node; ngOnInit() { this.node = this.sharedService.sharedNode; }
И, как любезно указал Ньюман, вы также можете иметь
this.sharedService.sharedNode
в шаблоне html или геттере:get sharedNode(){ return this.sharedService.sharedNode; }
источник
Да, вы можете установить входы компонентов, отображаемых через выходы маршрутизатора . К сожалению, вы должны делать это программно, как упоминалось в других ответах. Есть большая оговорка, когда задействованы наблюдаемые (описанные ниже).
Вот как:
(1) Подключитесь к
activate
событию роутера-розетки в родительском шаблоне:(2) Переключитесь на родительский файл машинописного текста и программно установите входные данные дочернего компонента каждый раз, когда они активируются:
Выполнено.
Однако приведенная выше версия
onOutletLoaded
упрощена для ясности. Это работает только в том случае, если вы можете гарантировать, что все дочерние компоненты имеют точно такие же входы, которые вы назначаете. Если у вас есть компоненты с разными входами, используйте защиты типов:Почему этот метод может быть предпочтительнее метода обслуживания?
Ни этот метод, ни метод службы не являются «правильным способом» взаимодействия с дочерними компонентами (оба метода отходят от чистой привязки к шаблону), поэтому вам просто нужно решить, какой способ больше подходит для проекта.
Этот метод, однако, позволяет избежать тесной связи, связанной с подходом «создать сервис для связи» (т. Е. Родитель нуждается в сервисе, а все потомки нуждаются в сервисе, что делает потомков непригодными для использования где-либо еще). Обычно предпочтение отдается развязке.
Во многих случаях этот метод также кажется более близким к «угловому способу», потому что вы можете продолжать передавать данные своим дочерним компонентам через @Inputs (это часть разделения - это позволяет повторно использовать в другом месте). Это также хорошо подходит для уже существующих или сторонних компонентов, которые вы не хотите или не можете тесно связать с вашим сервисом.
С другой стороны, это может показаться менее угловатым, когда ...
Предостережение
Предостережение с этим методом заключается в том, что, поскольку вы передаете данные в файл машинописного текста, у вас больше нет возможности использовать паттерн конвейерной асинхронности, используемый в шаблонах (например
{{ myObservable$ | async }}
) для автоматического использования и передачи наблюдаемых данных дочерним компонентам.Вместо этого вам нужно настроить что-то, чтобы получать текущие наблюдаемые значения при каждом
onChildLoaded
вызове функции. Скорее всего, это также потребует некоторого разрушения функции родительского компонентаonDestroy
. В этом нет ничего необычного, часто бывают случаи, когда это необходимо сделать, например, при использовании наблюдаемого, который даже не попадает в шаблон.источник
Обслуживание:
Составная часть:
источник
Есть 3 способа передать данные от родителей к детям
Через Children Router Resolver, если вам нужно получать разные данные
Через Parent Router Resolver, если вам нужно получать те же данные от родительского
Примечание 1: Вы можете прочитать о резолвере здесь . Также есть пример преобразователя и того, как зарегистрировать преобразователь в модуле, а затем получить данные из преобразователя в компонент. Регистрация преобразователя одинакова для родителя и ребенка.
Заметка 2: Вы можете прочитать об ActivatedRoute здесь , чтобы получить данные с маршрутизатора.
источник
Следуя этому вопросу, в Angular 7.2 вы можете передавать данные от родителя к потомку, используя состояние истории. Итак, вы можете сделать что-то вроде
Но будьте осторожны, чтобы быть последовательным. Например, предположим, что вы хотите отобразить список на левой боковой панели, а подробную информацию о выбранном элементе справа, используя выход маршрутизатора. Что-то типа:
Пункт 1 (x) | ..............................................
Пункт 2 (x) | ...... Сведения о выбранном элементе .......
Пункт 3 (x) | ..............................................
Пункт 4 (x) | ..............................................
Теперь предположим, что вы уже щелкнули по некоторым элементам. Если щелкнуть кнопки возврата в браузере, отобразятся сведения о предыдущем элементе. Но что, если тем временем вы нажали (x) и удалили этот элемент из своего списка? Затем, выполняя обратный щелчок, вы увидите подробную информацию об удаленном элементе.
источник