Angular - 在页面加载时访问 child 组件列表
Angular - Access list of child components on page load
我正在使用 Angular 10 作为我的 side-project。我有一个页面,在页面加载时,从服务器检索条目列表(在本例中特别是 spells
),并在该页面上为每个条目呈现 1 child-component(<app-spell>
组件) .用户可以(这是可选的)指定一个名为 name
的 url 参数,如果他这样做并且有一个条目是真的 spell.name === name
那么我想滚动到组件该条目。
我一直在努力寻找可以访问这些 children 列表的地方。 Ì 计划使用 ViewChildren
来获取 child-component 的列表。但是,似乎没有任何适当的生命周期挂钩具有准确的值。此外,即使在尝试使用 document.querySelector 时(我提前知道我将拥有一个 ID 为“Arawns-Changing-Scales”的组件),我似乎也无法获得所需的 HTML 元素:
ngAfterContentInit
:一般情况下,您不能在此挂钩中访问 ViewChildren
。 document.querySelector
-调用 return 为空。
ngAfterViewInit
:此时尚未获取条目,也未初始化 child-component。因此 ViewChildren
return 是一个空的 QueryList
。 document.querySelector` returns null
ngOnInit
: child-component尚未初始化。因此 ViewChildren
return 是一个空的 QueryList
。 document.querySelector
returns null
然后我就没有合适的生命周期钩子了。我已经尝试了建议 并将我尝试访问我的 ViewChildren
到 setTimeout 回调中,这只是 returned 与根本不使用超时相同。我发现的其他问题是使用点击或其他 user-triggered 事件来触发滚动,但我不是这种情况。
在加载页面期间,我在哪里可以获得某种 HTMLElements/Components?
## spells.component.html
<!-- Spells -->
<div *ngFor="let spell of spells; let i = index">
<app-spell
#spellElements
[id]="spell.name.replaceAll(' ', '-').replace('\'', '')"
[index] = "i"
[cardData] = "spell"
*ngIf="hasSelectedClasses(spell)"
></app-spell>
</div>
## spells.component.ts
@Component({
selector: 'app-spells',
templateUrl: './spells.component.html',
styleUrls: ['./spells.component.scss']
})
export class SpellsComponent implements OnInit, AfterContentInit, AfterViewInit {
panelIsOpenArray: boolean[];
spells: SpellObject[];
@ViewChildren("spellElements") spellElements: QueryList<any>;
constructor(
private spellService: SpellService,
public routingService: RoutingService,
private route: ActivatedRoute,
) { }
ngOnInit(): void {
this.spellService.list().pipe(first()).subscribe(
(spells: SpellObject[]) => {
this.spells = spells;
this.panelIsOpenArray = [];
for (let spell of spells){
this.panelIsOpenArray.push(true);
};
console.log("After init");
this.scrollToSpellInUrl();
},
error => this.routingService.routeToErrorPage(error)
);
}
ngAfterViewInit(): void{
setTimeout(_=> {
console.log("After view init in timeout");
this.scrollToSpellInUrl()
});
console.log("After view init normal")
this.scrollToSpellInUrl();
}
ngAfterContentInit(): void{
console.log("After content init");
this.scrollToSpellInUrl();
}
scrollToSpellInUrl(){
console.log(this.spellElements);
console.log(document.getElementById("Arawns-Changing-Scales");
console.log(document.querySelector("#Arawns-Changing-Scales"));
return;
}
hasSelectedClasses(spell: SpellObject): boolean{
//For all intents and purposes, based on some other data and this
//data this function returns sometimes true sometimes false, more
//is not relevant for this question.
}
}
您可以使用首先填充在 ngAfterViewInit 挂钩中的 ViewChildren annotation to watch for SpellComponents. The annotation exposes a QueryList。在您的情况下,您正在以异步方式获取法术,并且您无法及时获取 ngAfterViewInit 挂钩。然而,Querylist 有一个 changes
属性,它是一个 Observable,它会在任何时候在模板中添加、删除或移动 SpellComponent 时发出。
@ViewChildren(SpellComponent)
public spellsComponents: QueryList<SpellComponent>;
public ngAfterViewInit() {
this.spellsComponents.changes.subscribe(queryList => {});
}
在每次发出时,我们都可以在 queryList 参数中进行搜索。但在这是我的 SpellComponent 之前:
export class SpellComponent implements OnInit {
@Input() name: string;
constructor(public element: ElementRef) {}
ngOnInit() {}
}
我们将使用名称 Input 来标识我们的拼写组件。我注入 ElementRef as it will able us to use the element.scrollIntoView 方法。
this.spellsComponents.changes.subscribe(queryList => {
const target = queryList.find(cmp => cmp.name === "foo");
target.element.nativeElement.scrollIntoView();
});
完成。这是一个现场演示 https://stackblitz.com/edit/angular-mmjzwj-jffmyr?file=app.module.ts。
我正在使用 Angular 10 作为我的 side-project。我有一个页面,在页面加载时,从服务器检索条目列表(在本例中特别是 spells
),并在该页面上为每个条目呈现 1 child-component(<app-spell>
组件) .用户可以(这是可选的)指定一个名为 name
的 url 参数,如果他这样做并且有一个条目是真的 spell.name === name
那么我想滚动到组件该条目。
我一直在努力寻找可以访问这些 children 列表的地方。 Ì 计划使用 ViewChildren
来获取 child-component 的列表。但是,似乎没有任何适当的生命周期挂钩具有准确的值。此外,即使在尝试使用 document.querySelector 时(我提前知道我将拥有一个 ID 为“Arawns-Changing-Scales”的组件),我似乎也无法获得所需的 HTML 元素:
ngAfterContentInit
:一般情况下,您不能在此挂钩中访问ViewChildren
。document.querySelector
-调用 return 为空。ngAfterViewInit
:此时尚未获取条目,也未初始化 child-component。因此ViewChildren
return 是一个空的QueryList
。 document.querySelector` returns nullngOnInit
: child-component尚未初始化。因此ViewChildren
return 是一个空的QueryList
。document.querySelector
returns null
然后我就没有合适的生命周期钩子了。我已经尝试了建议 ViewChildren
到 setTimeout 回调中,这只是 returned 与根本不使用超时相同。我发现的其他问题是使用点击或其他 user-triggered 事件来触发滚动,但我不是这种情况。
在加载页面期间,我在哪里可以获得某种 HTMLElements/Components?
## spells.component.html
<!-- Spells -->
<div *ngFor="let spell of spells; let i = index">
<app-spell
#spellElements
[id]="spell.name.replaceAll(' ', '-').replace('\'', '')"
[index] = "i"
[cardData] = "spell"
*ngIf="hasSelectedClasses(spell)"
></app-spell>
</div>
## spells.component.ts
@Component({
selector: 'app-spells',
templateUrl: './spells.component.html',
styleUrls: ['./spells.component.scss']
})
export class SpellsComponent implements OnInit, AfterContentInit, AfterViewInit {
panelIsOpenArray: boolean[];
spells: SpellObject[];
@ViewChildren("spellElements") spellElements: QueryList<any>;
constructor(
private spellService: SpellService,
public routingService: RoutingService,
private route: ActivatedRoute,
) { }
ngOnInit(): void {
this.spellService.list().pipe(first()).subscribe(
(spells: SpellObject[]) => {
this.spells = spells;
this.panelIsOpenArray = [];
for (let spell of spells){
this.panelIsOpenArray.push(true);
};
console.log("After init");
this.scrollToSpellInUrl();
},
error => this.routingService.routeToErrorPage(error)
);
}
ngAfterViewInit(): void{
setTimeout(_=> {
console.log("After view init in timeout");
this.scrollToSpellInUrl()
});
console.log("After view init normal")
this.scrollToSpellInUrl();
}
ngAfterContentInit(): void{
console.log("After content init");
this.scrollToSpellInUrl();
}
scrollToSpellInUrl(){
console.log(this.spellElements);
console.log(document.getElementById("Arawns-Changing-Scales");
console.log(document.querySelector("#Arawns-Changing-Scales"));
return;
}
hasSelectedClasses(spell: SpellObject): boolean{
//For all intents and purposes, based on some other data and this
//data this function returns sometimes true sometimes false, more
//is not relevant for this question.
}
}
您可以使用首先填充在 ngAfterViewInit 挂钩中的 ViewChildren annotation to watch for SpellComponents. The annotation exposes a QueryList。在您的情况下,您正在以异步方式获取法术,并且您无法及时获取 ngAfterViewInit 挂钩。然而,Querylist 有一个 changes
属性,它是一个 Observable,它会在任何时候在模板中添加、删除或移动 SpellComponent 时发出。
@ViewChildren(SpellComponent)
public spellsComponents: QueryList<SpellComponent>;
public ngAfterViewInit() {
this.spellsComponents.changes.subscribe(queryList => {});
}
在每次发出时,我们都可以在 queryList 参数中进行搜索。但在这是我的 SpellComponent 之前:
export class SpellComponent implements OnInit {
@Input() name: string;
constructor(public element: ElementRef) {}
ngOnInit() {}
}
我们将使用名称 Input 来标识我们的拼写组件。我注入 ElementRef as it will able us to use the element.scrollIntoView 方法。
this.spellsComponents.changes.subscribe(queryList => {
const target = queryList.find(cmp => cmp.name === "foo");
target.element.nativeElement.scrollIntoView();
});
完成。这是一个现场演示 https://stackblitz.com/edit/angular-mmjzwj-jffmyr?file=app.module.ts。