Angular 13点赞组件状态持久化问题:刷新后状态丢失如何解决
Angular 13 点赞状态刷新后不重置的解决方案
问题说明
在Angular 13项目中实现点赞功能,要求:点击点赞按钮切换图标填充状态、动态显示点赞数,页面刷新后仍保持已点赞状态。目前点击切换正常,但刷新页面后点赞状态会变回未点赞,需要解决状态持久化问题,同时支持已点赞时点击取消。
现有代码
HTML模板
<div class="likes"> <div *ngIf="!isLiked"> <i class="fa fa-heart-o" (click)="likeTweet(tweet.id)"></i> </div> <div *ngIf="isLiked"> <i class="fa fa-heart" (click)="unlikeTweet(tweet.id)"></i> </div> <div class="likes-count"> {{getLikes}} </div> </div>
组件代码
isLiked: boolean = false; like: Like = new Like(); likeTweet(tweetId: number){ this.likeService.likeTweet(tweetId, this.like).subscribe(response => { this.like = response; this.isLiked = true; }); } unlikeTweet(tweetId: number){ this.likeService.unlikeTweet(tweetId).subscribe(response => { console.log(response); this.isLiked = false; }); } getTweetLikes(){ const tweetId = this.route.snapshot.params['tweetId']; this.likeService.getTweetLikes(tweetId).subscribe(response => { this.likes = response; }) } likes: LikeModel[]; get getLikes(){ return this.likes.length; }
服务代码
url: string = environment.apiBaseUrl; // localhost:8080 constructor(private http: HttpClient) { } likeTweet(tweetId: number, like: Like){ return this.http.post<Like>(`${this.url}/like/tweet/${tweetId}`,like); } unlikeTweet(tweetId: number){ return this.http.delete<Like>(`${this.url}/unlike/tweet/${tweetId}`); } getTweetLikes(tweetId: number){ return this.http.get<LikeModel[]>(`${this.url}/tweet/${tweetId}/likes`); }
实体类代码
export class Like { id: number; likedTweet: Tweet; likedComment: Comment; user: User; } export class LikeModel { username: string; }
解决步骤
核心是页面加载时从后端获取当前用户的点赞状态,而不是默认设为false,具体实现分两种方式:
方式一:新增后端接口直接获取状态
- 在
LikeService中新增接口方法:
isTweetLikedByUser(tweetId: number) { return this.http.get<boolean>(`${this.url}/tweet/${tweetId}/is-liked`); }
后端需要根据当前登录用户和推文ID,返回true(已点赞)或false(未点赞)。
- 在组件初始化时调用该接口:
// 组件中添加ngOnInit生命周期钩子 ngOnInit(): void { this.getTweetLikes(); this.loadCurrentLikeStatus(); } loadCurrentLikeStatus() { const tweetId = this.route.snapshot.params['tweetId']; this.likeService.isTweetLikedByUser(tweetId).subscribe(status => { this.isLiked = status; }); }
方式二:通过现有点赞列表判断状态
如果不想新增后端接口,可利用已有的getTweetLikes接口,在获取点赞列表后检查当前登录用户是否在列表中:
// 先获取当前登录用户的用户名(从认证服务或本地存储中获取) currentUsername: string = '当前登录用户用户名'; getTweetLikes(){ const tweetId = this.route.snapshot.params['tweetId']; this.likeService.getTweetLikes(tweetId).subscribe(response => { this.likes = response; // 检查当前用户是否在点赞列表里,更新isLiked状态 this.isLiked = this.likes.some(item => item.username === this.currentUsername); }) }
可选优化:简化模板代码
把两个*ngIf合并,减少DOM元素:
<div class="likes"> <i class="fa" [class.fa-heart-o]="!isLiked" [class.fa-heart]="isLiked" (click)="isLiked ? unlikeTweet(tweet.id) : likeTweet(tweet.id)" ></i> <div class="likes-count">{{getLikes}}</div> </div>
可选优化:确保数据一致性
在点赞/取消点赞成功后,重新获取点赞列表,保证点赞数和状态同步:
likeTweet(tweetId: number){ this.likeService.likeTweet(tweetId, this.like).subscribe(response => { this.like = response; this.isLiked = true; this.getTweetLikes(); // 刷新点赞数 }); } unlikeTweet(tweetId: number){ this.likeService.unlikeTweet(tweetId).subscribe(response => { console.log(response); this.isLiked = false; this.getTweetLikes(); // 刷新点赞数 }); }
内容的提问来源于stack exchange,提问作者Ruschisb
相关产品推荐
相关产品推荐

