问题描述
我有一个@ViewChildren的奇怪行为,它对应于ngFor生成的子组件. @ViewChildren查询在很长一段时间内都看不到元素在数组中站立.我所有的代码都在 Plunker -在打开控制台的情况下进行查看.
I have a strange behaviour of @ViewChildren corresponding to children components generated by ngFor. @ViewChildren query does not see element standing in array for a quite long time. All my code is in the Plunker - see with console opened.
这是我的主要组成部分:
This is my main component:
@Component({
selector: 'my-app',
template: `
<button (click)="addInternalComponent()">Add internal component</button>
<app-internal #internals *ngFor="let i of indexes" [index]="i
(afterViewInit)="onAfterViewInit()"></app-internal>
`,
})
export class App {
@ViewChildren('internals') internals: QueryList<InternalComponent>;
indexes = [];
addInternalComponent() {
console.log('adding internal component!');
this.indexes.push(this.indexes.length);
console.log('Not complete list', this.internals._results);
}
onAfterViewInit() {
console.log('onAfterViewInit - still not complete list', this.internals._results);
}
}
哪些子组件可以通过单击按钮添加.
Which has come children components that we can add by clicking a button.
在将元素添加到可以在ngFor循环中生成所有子代的indexs数组中之后-我们没有刚刚添加的那个子代.
After adding an element into indexes array that generates all children in ngFor loop - we don't have that one that we just have added.
我可以理解这种行为-因为子组件可能需要一些时间来创建它,并且引擎决定在创建完整子组件之前控制台日志.
I can understand that behaviour - because maybe child component needs some time to create it and engine decides to console log before creating full child component.
但是,我在子组件中创建了发射器,表示子视图和模型均已初始化.但是...在父组件中处理此事件-我们仍然不知何故没有此项.这怎么可能?
However I created emitter in child component signaling that both child's view and model are initialised. But... Handling this event in parent component - we still somehow doesn't have this item. How even is this possible?
子组件:
export class InternalComponent implements AfterViewInit {
@Input()
index;
@Output()
afterViewInit: EventEmitter<any> = new EventEmitter<any>();
ngAfterViewInit() {
this.afterViewInit.emit();
}
}
推荐答案
用于通知QueryList
的内容已更改为订阅ngAfterViewInit
中changes
事件的标准方法:
The standard way to be notified that the content of a QueryList
has changed it to subscribe to its changes
event in ngAfterViewInit
:
@ViewChildren("internals") internals: QueryList<InternalComponent>;
ngAfterViewInit() {
this.internals.changes.subscribe((list: QueryList<InternalComponent>) => {
// The updated QueryList is available here (with list or with this.internals)
this.doSomethingWithInternals(list);
this.doSomethingWithNewInternal(list.last);
...
});
}
上面的事件处理可能就是您所需要的.如果仍要在InternalComponent
中实现afterViewInit
事件,则可以将对组件的引用作为事件的参数传递:
The event handling above may be all you need. If you still want to implement the afterViewInit
event in InternalComponent
, you can pass a reference to the component as a parameter of the event:
export class InternalComponent implements AfterViewInit {
@Output() afterViewInit = new EventEmitter<InternalComponent>();
ngAfterViewInit() {
this.afterViewInit.emit(this);
}
}
并在事件处理程序中检索组件:
and retrieve the component in the event handler:
(afterViewInit)="onAfterViewInit($event)"
onAfterViewInit(component: InternalComponent) {
this.useNewInternalComponent(component);
...
}
这篇关于Angular ViewChildren不会立即从ngFor中看到所有子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!