使用TypeScript修改点赞按钮颜色 解决状态识别与样式不生效问题
问题解决方法
你遇到的两个问题可以通过调整判断逻辑、改用Angular框架原生的样式绑定能力解决,具体如下:
问题原因说明
- 报错
TypeError: Cannot read property 'style' of null
- 你在类属性声明阶段直接执行
document.getElementById('like'),此时组件还未完成DOM渲染,对应元素不存在,拿到的结果自然是null - 你做的是帖子列表,所有帖子的点赞按钮都用了相同的
id="like",id是全局唯一属性,就算后续能拿到元素,也只能匹配到第一个帖子的点赞按钮,无法对应到当前操作的帖子 - Angular本身提供了属性绑定能力实现样式动态切换,不需要手动操作DOM,也能规避时序和元素匹配错误的问题
this.post.likes.includes(parseInt(id))始终返回false
- 后端返回的
post.likes是对象数组,每个元素是包含userId字段的点赞记录对象,不是纯数字数组,你直接把用户ID数字传入includes方法,永远无法匹配到对象类型的数组成员,所以结果永远是false
实现代码
1. 样式定义
先给已点赞状态写好样式:
.liked { color: red; }
2. HTML模板调整
去掉重复的id,改用Angular的类绑定动态切换已点赞样式:
<button (click)="liked(post)" class="btn mr-5" [class.liked]="isLiked"> Like<em class="fa fa-thumbs-up"></em> {{post.likes.length}} </button>
3. TypeScript逻辑调整
在组件初始化阶段就判断点赞状态,用Array.some方法匹配用户ID:
import { Component, Input, OnInit } from '@angular/core'; // 其他原有引入保持不变 @Component({ // 你的原有组件配置保持不变 }) export class 你的组件名 implements OnInit { @Input() post: Post; // 存储当前用户是否已点赞的状态 isLiked = false; // 缓存当前登录用户ID,避免重复读取解析 private currentUserId: number; constructor(private postService: PostsService) {} ngOnInit(): void { // 组件初始化、拿到post数据后就判断点赞状态 const user: User = JSON.parse(localStorage.getItem('user')); this.currentUserId = parseInt(this.getDecodedToken(user.token).nameid); // 遍历点赞列表判断是否有当前用户的点赞记录 this.isLiked = this.post.likes.some(like => like.userId === this.currentUserId); } liked(post: Post): void { this.postService.setLike(this.currentUserId, post.id); // 临时切换本地状态,等SignalR推送最新点赞列表后,可以在更新回调里重新给isLiked赋值保证和后端同步 this.isLiked = !this.isLiked; } }
补充说明
如果你的SignalR会实时更新post.likes数组,可以在收到更新推送的回调里,重新执行一次this.isLiked = this.post.likes.some(like => like.userId === this.currentUserId),保证状态和后端完全同步,避免本地切换和后端实际状态不一致的问题。
内容的提问来源于stack exchange,提问作者Alessia
相关产品推荐
相关产品推荐

