Angular 2 - Передача данных в дочерний компонент после родительской инициализации

У меня есть родительский компонент, который получает данные с сервера через службу. Мне нужно, чтобы некоторые из этих данных были переданы в дочерний компонент.

Я пытался передать эти данные с обычным@Input() Однако, как я ожидал, данные, которые я получаю в дочернем компоненте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 от команды Angular, демонстрирующий крюки жизненного цикла. В тесте я обновил OnChangesComponent для передачи объекта, который, как видно из примера при обновлении объекта, ngOnChanges не обнаруживает изменения. (Это также показано в этомвопрос)

https://plnkr.co/edit/KkqwpsYKXmRAx5DK4cnV

Кажется, чтоngDoCheck может помочь решить эту проблему, но мне кажется, что это не поможет производительности в долгосрочной перспективе, так как каждое изменение обнаруживается этим Lifecycle Hook.

Также я знаю, что я мог бы использовать@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);
    }
}

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

Обновить

Я ценю, что пользователи все еще публикуют ответы на этот вопрос. Обратите внимание, что код, который был размещен выше, работал для меня. Проблема, с которой я столкнулся, заключалась в том, что в конкретном шаблоне была опечатка, из-за которой данные былиundefined.

Надеюсь, что это окажется полезным :)

Ответы на вопрос(5)

Ваш ответ на вопрос