[英]document.getelementbyid always returns null in angular 13
I have a component like this我有这样的组件
export class NotificationPostComponent extends PostComponent implements OnInit, AfterViewInit {
commentsDto: IComment[] = [];
commentId = '';
ngOnInit(): void {
this.route.data.subscribe(data=>{
this.post = data.post;
});
this.route.params.subscribe((param : Params) => {
const slug = param['slug'];
this.commentId = param['commentid'];
this.notifiService.loadCommentsOfPost(slug, this.commentId).subscribe(data=>{
this.commentsDto = data.comments;
})
});
super.ngOnInit();
}
ngAfterViewInit(): void {
var idDiv = document.getElementById(this.commentId)
console.log(idDiv)
}
}
This is a html with id is Guid:这是一个 html,id 是 Guid:
<div id="{{cmt.id}}" *ngFor="let cmt of commentsDto">
<div>comment</div>
</div>
the problem is that after view is initialized its document.getElementById is always null. Please tell me where did I go wrong?问题是视图初始化后,它的 document.getElementById 总是 null。请告诉我 go 哪里错了?
Instead of using document.getElementById
you can use Angular's built-in API: @ViewChildren .除了使用document.getElementById
,您还可以使用 Angular 的内置 API: @ViewChildren 。
Then, the inline Template could be extracted into a new component.然后,可以将内联模板提取到新组件中。
Template模板
<button (click)="scrollToBottom()">Scroll to last comment</button>
<app-comment [title]="comment.title" *ngFor="let comment of comments$ | async">
</app-comment>
<button (click)="scrollToTop()">Scroll to 1st Comment</button>
In the Component, use ViewChildren to access the collection of your CommentComponents represented by a QueryList .在组件中,使用ViewChildren访问由QueryList表示的CommentComponents 集合。
If you need to access the HTML-Element directly, you need to configure @ViewChildren to read the ElementRefence ( @ViewChildren(CommentComponent, { read: ElementRef })
).如果您需要直接访问 HTML 元素,则需要配置 @ViewChildren 以读取 ElementRefence ( @ViewChildren(CommentComponent, { read: ElementRef })
)。
Component成分
export class NotificationPostComponent extends PostComponent
implements OnInit, AfterViewInit {
comments$ = /* Stream of Comments */
@ViewChildren(CommentComponent, { read: ElementRef })
commentElementReferences: QueryList<ElementRef<HTMLElement>> | undefined;
}
Next, if you need to scroll to a specific element by a ID or something like that, you can mark each Comment Component with an attr-Binding
.接下来,如果您需要通过 ID 或类似的东西滚动到特定元素,您可以使用attr-Binding
标记每个评论组件。
Template模板
<app-comment
[title]="comment.title"
[attr.data-anchor]="comment.id"
*ngFor="let comment of comments$ | async"
>
</app-comment>
Now, you can add some logic to your component finding the Element you need, allowing you to scroll to it.现在,您可以向您的组件添加一些逻辑来查找您需要的元素,从而允许您滚动到它。
Component成分
private scrollToCommentById(id: string) {
if (!this.commentElementReferences) return;
const commentToScrollTo = this.commentElementReferences
.map((reference) => reference.nativeElement)
.find((element) => element.getAttribute('data-anchor') === id);
commentToScrollTo.scrollIntoView({ behavior: 'smooth' });
}
Finally, you can connect to the activated route, triggering your scrolling mechanism when navigation kicks in.最后,您可以连接到激活的路线,在导航开始时触发您的滚动机制。
ngAfterViewInit(): void {
// Listen to parameter changes in route
this.activatedRoute.paramMap
.pipe(
map((paramMap) => paramMap.get('id')),
filter((id) => !!id),
tap((id) => this.scrollToCommentById(id))
)
.subscribe();
}
Demo演示
This StackBlitz @ViewChild Demo shows how everything can be set up. 这个 StackBlitz @ViewChild 演示展示了如何设置所有内容。 There you also see how the button is set up that scrolls to a specific Comment by its ID.您还可以看到按钮是如何设置的,它可以通过 ID 滚动到特定的 Comment。
<!--see the tempalte reference variable "#comment"-->
<div #comment id="{{cmt.id}}" *ngFor="let cmt of commentsDto">
<div>comment</div>
</div>
//In commentsyou has the "QueryList" (an specie of array)
@ViewChildren('comment') comments:QueryList<ElementRef>
this.notifiService.loadCommentsOfPost(slug, this.commentId).subscribe(data=>{
this.commentsDto = data.comments;
//you neeed wait Angular "render" the elements
setTimeout(()=>{
const comment=this.comments
.find(x=>x.nativeElement.getAttribute('id')==myId)
if (comment)
comment.nativeElement.scrollIntoView(
{Behaivor:"Smooth",Block:Start,inline:"Nearest"})
})
})
Well, you can find using "nativeElement.getAttribute" or find the index of the comment and find the element at this index.好吧,你可以使用“nativeElement.getAttribute”找到或者找到评论的索引并在这个索引处找到元素。 some like有些喜欢
const index=this.commentsDto.findIndex(x=>x.id==myInd)
const comment=this.comments
.find((_,i)=>i==index)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.