У меня есть родительский компонент, который получает данные с сервера через службу. Мне нужно, чтобы некоторые данные передавались компоненту Child.Угловой 2 - Передача данных дочернему компоненту после инициализации родителя
Я пытался передать эти данные обычным @Input()
, однако, как я и ожидал, данные, которые я получаю в компоненте Child, составляют undefined
.
Пример
Родитель Компонент
@Component({
selector: 'test-parent',
template: `
<test-child [childData]="data"></test-child>
`
})
export class ParentComponent implements OnInit {
data: any;
ngOnInit() {
this.getData();
}
getData() {
// calling service and getting data
this.testService.getData()
.subscribe(res => {
this.data = res;
});
}
}
Детский компонент
@Component({
selector: 'test-child',
template: `
<!-- Content for child.... -->
`
})
export class ChildComponent implements OnInit {
@Input() childData: any;
ngOnInit() {
console.log(childData); // logs undefined
}
}
я сохранил пример простой для того, чтобы показать, что я пытаюсь делать. Мой вопрос заключается в том, можно ли передавать данные ребенку после инициализации. Я не уверен, но в этом случае поможет двусторонняя привязка данных?
Подробнее Исследование
После посланных ответов я попытался с помощью ngOnChanges
жизненный цикл крюк. Проблема, с которой я сталкиваюсь, заключается в том, что функция ngOnChanges
не запускается, когда данные обновляются. Данные являются объектом, поэтому я думаю, что изменения не обнаруживаются.
Обновленный код в дочерних компонентах
@Component({
selector: 'test-child',
template: `
<!-- Content for child.... -->
`
})
export class ChildComponent implements OnChanges {
@Input() childData: any;
ngOnChanges() {
console.log(childData); // logs undefined
}
}
Я попытался тест с живыми примерами на Plunker от угловой команды демонстрирующего Lifecycle Крючков. В тесте я обновил OnChangesComponent для передачи объекта, который, как видно из примера при обновлении объекта, ngOnChanges не обнаруживает изменения. (Это также показано в этом question)
https://plnkr.co/edit/KkqwpsYKXmRAx5DK4cnV
Кажется, что ngDoCheck
может помочь решить эту проблему, но мне кажется, что это не помогло бы производительности в долгосрочной перспективе, поскольку каждое изменение обнаруживается это Крюк жизненного цикла.
Также я знаю, что я мог бы использовать @ViewChild()
для доступа к Детскому компоненту и задать переменные, которые мне нужны, но я не думаю, что для этого прецедента это имеет смысл.
Проводка больше коды, чтобы помочь объяснить лучше
родительского компонент
@Component({
selector: 'test-parent',
template: `
<test-child [childType]="numbers" [childData]="data" (pickItem)="pickNumber($event)">
<template let-number>
<span class="number" [class.is-picked]="number.isPicked">
{{ number.number }}
</span>
</template>
</test-child>
<test-child [childType]="letters" [childData]="data" (pickItem)="pickLetter($event)">
<template let-letter>
<span class="letter" [class.is-picked]="letter.isPicked">
{{ letter.displayName }}
</span>
</template>
</test-child>
<button (click)="submitSelections()">Submit Selection</button>
`
})
export class ParentComponent implements OnInit {
data: any;
numbersData: any;
lettersData: any;
ngOnInit() {
this.getData();
}
getData() {
// calling service and getting data for the game selections
this.testService.getData()
.subscribe(res => {
this.data = res;
setChildData(this.data);
});
}
setChildData(data: any) {
for(let i = 0; i < data.sections.length; i++) {
if(data.sections[i].type === 'numbers') {
this.numbersData = data.sections[i];
}
if(data.sections[i].type === 'letters') {
this.lettersData = data.sections[i];
}
}
}
pickNumber(pickedNumbers: any[]) {
this.pickedNumbers = pickedNumbers;
}
pickLetter(pickedLetters: any[]) {
this.pickedLetters = pickedLetters;
}
submitSelections() {
// call service to submit selections
}
}
Детского компонент
@Component({
selector: 'test-child',
template: `
<!--
Content for child...
Showing list of items for selection, on click item is selected
-->
`
})
export class ChildComponent implements OnInit {
@Input() childData: any;
@Output() onSelection = new EventEmitter<Selection>;
pickedItems: any[];
// used for click event
pickItem(item: any) {
this.pickedItems.push(item.number);
this.onSelection.emit(this.pickedItems);
}
}
Это более или менее код, который у меня есть. В основном у меня есть родитель, который обрабатывает выбор из дочерних компонентов, а затем я отправляю эти варианты в службу.Мне нужно передать определенные данные ребенку, потому что я пытаюсь получить объект, который возвращает ребенок в том формате, который ожидает служба. Это поможет мне не создавать весь объект, ожидаемый службой в родительском компоненте. Также это сделало бы ребенка повторно используемым в том смысле, что он отправит обратно то, что ожидает служба.
Update
Я понимаю, что пользователи по-прежнему размещения ответов на этот вопрос. Обратите внимание, что код, который был выше, работал для меня. Проблема была в том, что в конкретном шаблоне у меня была опечатка, которая привела к тому, что данные были undefined
.
Надеется, что это оказывается полезными :)
Спасибо за ваш ответ, кажется, указал мне в правильном направлении. Единственная проблема, с которой я столкнулся сейчас, состоит в том, что если данные были «простой» строкой, «ngOnChanges» обнаруживает изменения, однако, если это объект по какой-либо причине, он остается «неопределенным». –
@ DanielGrima: Обновлен ответ. –
Еще раз спасибо за вашу помощь ... Я только выяснил, в чем проблема. Имела опечатка в моей переменной шаблона, и поэтому она всегда была неопределенной, конечно. Не понял раньше! По крайней мере, похоже, что он работает, и, по-видимому, мне не нужны никакие «ngOnChanges» или геттеры для объекта. Теперь все в порядке. –