Передача массива интерфейсов между компонентами angular 2

у меня возникли проблемы при передаче данных (массива) между компонентами через @Input, есть некоторый код. родитель.component.ts:

public ngOnInit() {
    this.applications = new Array<ApplicationEntryInterface>();
(...)
let shortTermData = new ShortTermApplicationAdapter(application);
this.applications.push(shortTermData);
console.log(this.applications);
}

этот console.log показывает мне обычный массив введите здесь описание изображения parent.component.html

<student-application-overview [applicationsEntry]="applications"></student-application-overview>

Дочерний компонент:

@Input('applicationsEntry') public applicationsEntry: Array<ApplicationEntryInterface>;
 ngOnChanges() {
console.log(this.applicationsEntry);
console.log(this.applicationsEntry.length); <--- shows 0
}

который показывает введите описание изображения здесь Невозможно перебрать его в for, foreach и т. д., работает только *ngFor, this.applicationsEntry.length равно 0, как мне с этим справиться? Также я использовал @Input (..) set (..) { (..) } и дал тот же результат


person Jędrek Markowski    schedule 02.10.2017    source источник
comment
То, как вы передаете массив в свой дочерний компонент, выглядит правильно, и если этот второй снимок экрана является журналом вашего дочернего элемента, он тоже выглядит правильно. Можем ли мы увидеть, где вы вызываете forEach или length в коде вашего компонента? Мое лучшее предположение состоит в том, что массив, который вы передаете, не будет сразу доступен в вашем дочернем компоненте, особенно если *ngFor в вашем шаблоне HTML работает   -  person Jack Koppa    schedule 02.10.2017
comment
Только что отредактировано, то же самое forEach обрабатывает этот массив как 0-длину.   -  person Jędrek Markowski    schedule 02.10.2017
comment
Хорошо, я только что понял, что использовал асинхронную функцию в родительском компоненте (связь с остальными API), в любом случае, новейший массив не устанавливается при изменениях (только тело).   -  person Jędrek Markowski    schedule 02.10.2017
comment
Хм, попался. Похоже, что асинхронность, не запускающая обнаружение изменений, может быть связана с этот вопрос, который не имел удовлетворительного решения. Один из вариантов (если обнаружение изменений действительно является проблемой) — передать второй ввод (например, changeTrigger), не связанный с асинхронным вызовом, который вы обновляете, когда возвращаете результат своего асинхронного вызова. Когда вы вызываете changeTrigger++ в родительском, это вызовет ngOnChanges в дочернем   -  person Jack Koppa    schedule 02.10.2017
comment
Однако, не видя plunkr, сложно точно сказать, что сработает. И я вполне уверен, что есть более элегантное решение, чем то, что я упомянул выше.   -  person Jack Koppa    schedule 02.10.2017
comment
Спасибо, ребята, наконец-то я использовал ViewChild и изменил переменную в конце асинхронной функции.   -  person Jędrek Markowski    schedule 03.10.2017


Ответы (3)


Проблема заключается в ChangeDetection Angular и в том, как вы «обновляете» свойство Array в родительском компоненте.

Просто добавляя новые элементы в массив, дочерние компоненты не замечаются в обработчике жизненного цикла OnChanges.

Если вы хотите решить эту распространенную проблему, на родительском компоненте сделайте что-то подобное:

let shortTermData = new ShortTermApplicationAdapter(application);
this.applications.push(shortTermData);
this.applications = [...this.applications]; // Here is the "magic"

Последняя строка создает новую глубокую копию массива и позволяет обнаружить изменения в массивах с помощью ChangeDetection Angular.

person MiguelSsSRrR    schedule 11.04.2018

Я очень новичок в Angular, но я всегда использую этот синтаксис для ввода

@Input() applicationsEntry: Array<ApplicationEntryInterface>;
person Eliseo    schedule 02.10.2017

Я использую ngOnChanges с изменениями. Это изменится только в том случае, если текущее значение отличается от предыдущего значения, но если вы создаете объект каждый раз, он должен работать нормально.

changes будет записывать каждый элемент, измененный в компоненте.

Пытаться:

ngOnChanges(changes: any) {
        if (changes.applicationsEntry) { // this help to filter out undefined
           console.log(changes.applicationsEntry.currentValue); // your current array should be here
        }
    }
person Swoox    schedule 02.10.2017