Angular获取postCreator Id实现点击用户名跳转用户profile问题
问题描述
更新:经查阅资料我发现,无法直接渲染subscribe()函数中被Observable持续修改的值。请问该如何将onUserNameClick相关逻辑移入subscribe中,同时保留仅点击用户名时才跳转至用户profile的功能?
我学习编程已有3个月,目前正在通过搭建带社区功能的招聘板项目练习。我尝试获取postCreator的id,用于实现跳转至用户profile的功能,但始终无法在控制台打印出该值,不清楚代码哪里出错了。
原问题代码
组件TS代码
ngOnInit() { this.postId = this.route.snapshot.paramMap.get('postId'); this.postsService.getPost(this.postId) .subscribe(selectPostData => { this.post = { postId: selectPostData.data._id, postTitle: selectPostData.data.postTitle, postContent: selectPostData.data.postContent, postVote: selectPostData.data.postVote, postCreator: selectPostData.data.postCreator, postCreatedAt: selectPostData.data.createdAt, image: selectPostData.data.image }; // console.log(this.post) this.userId = this.post.postCreator._id }); console.log(this.userId) } // getCreatorInfo(){ // this.post.postCreator // console.log(this.post) // } onUserNameClick (userId: any){ this.router.navigate(['/user-profile', userId])
模板HTML代码
<a href="/user-profile" class="post-page__creator" (click)="onUserNameClick(post.postCreator._id)" >by <span> {{ post.postCreator.userName }} </span> </a>
解答
控制台打印userId拿不到值的核心原因是异步执行时序问题:
this.postsService.getPost()是异步HTTP请求,subscribe内的回调逻辑会等接口返回响应后才会执行- 写在subscribe外部的
console.log(this.userId)是同步代码,会在组件初始化阶段立刻执行,此时接口还未返回、this.userId尚未被赋值,自然无法打印出正确值。
你更新里提到的“无法直接渲染subscribe中被Observable修改的值”是认知偏差:Angular自带变更检测机制,只要subscribe中给类属性(挂载在this上的变量)赋值,赋值完成后模板会自动更新渲染对应内容,不需要把点击交互逻辑硬塞进subscribe回调里。你之前功能异常是踩了两个小坑:一是没有做初始空值判断,接口未返回时模板就尝试访问post.postCreator属性,触发空指针报错导致渲染失败;二是没有拦截a标签的默认跳转行为,点击时会优先走href属性的原生跳转,不会执行你写的路由跳转逻辑。
按以下方式修改即可实现需求:
- 组件初始化时给
post设置初始空值,模板中加*ngIf判断,等接口返回、post赋值完成后再渲染用户名区域,避免空指针错误 - 点击事件中传入事件对象,拦截a标签默认跳转,校验userId有效性后再执行路由跳转
修改后的代码如下:
修正后的TS代码
ngOnInit() { this.postId = this.route.snapshot.paramMap.get('postId'); // 初始化post为null,避免模板初始渲染时空指针报错 this.post = null; this.postsService.getPost(this.postId) .subscribe(selectPostData => { this.post = { postId: selectPostData.data._id, postTitle: selectPostData.data.postTitle, postContent: selectPostData.data.postContent, postVote: selectPostData.data.postVote, postCreator: selectPostData.data.postCreator, postCreatedAt: selectPostData.data.createdAt, image: selectPostData.data.image }; this.userId = this.post.postCreator._id // 打印异步值必须写在subscribe回调内部,才能拿到接口返回的结果 console.log('获取到的创作者ID:', this.userId) }); } onUserNameClick (userId: string, event: Event){ // 阻止a标签默认的原生跳转行为 event.preventDefault(); // 存在有效用户ID时才执行跳转 if(userId) { this.router.navigate(['/user-profile', userId]) } }
修正后的HTML模板代码
<!-- 等post赋值完成后再渲染该区域,避免访问空对象属性报错 --> <a *ngIf="post" href="/user-profile" class="post-page__creator" (click)="onUserNameClick(post.postCreator._id, $event)" >by <span> {{ post.postCreator.userName }} </span> </a>
内容的提问来源于stack exchange,提问作者Francis
相关产品推荐
相关产品推荐

