如何在TypeScript中避免Observable.interval间隔执行时触发日期排序
解决方案:让日期排序仅在用户手动触发时执行
我明白你的需求:现在每次间隔任务拉取新的通知数据后,之前的排序会被打乱,而且你不希望间隔更新时自动执行排序,只保留用户点击「Time」复选框时的排序操作。下面给你两种实用的实现方式:
方法1:用状态开关控制排序时机
咱们可以加一个布尔变量当开关,只有用户点击复选框时才开启排序状态,间隔任务更新数据后,只有开关开启时才重新排序。
步骤1:在组件里加状态变量
先在组件类里声明一个控制排序的开关:
// 标记是否需要按日期排序 isSortByDateEnabled = false;
步骤2:修改排序函数和复选框点击逻辑
更新sortbydate()方法,让它切换排序开关,同时执行排序(或者取消排序):
public sortbydate() { this.isSortByDateEnabled = !this.isSortByDateEnabled; if (this.isSortByDateEnabled) { // 开启排序:对当前通知数据按日期排序 this.notification.sort((a, b) => { return this.getTime(new Date(a.datetime_device)) - this.getTime(new Date(b.datetime_device)); }); } else { // 关闭排序:可以选择恢复原始顺序,比如重新拉取一次数据 this.getAllNotifications(); } }
步骤3:调整间隔任务的逻辑
在间隔任务拉取完新数据后,判断开关状态,只有开启时才重新排序:
this.subscription = Observable.interval(10000).subscribe(x => { // 先拉取新数据 this.getAllNotifications().then(() => { // 如果用户开启了按时间排序,就重新执行排序 if (this.isSortByDateEnabled) { this.notification.sort((a, b) => { return this.getTime(new Date(a.datetime_device)) - this.getTime(new Date(b.datetime_device)); }); } }); });
小贴士:如果
getAllNotifications()是同步方法,直接在获取数据后判断开关状态即可,不用then()。
方法2:保存原始数据副本,按需切换显示
另一种思路是存一份未排序的原始数据,用户点击排序时,对副本排序后展示;间隔任务更新时只更新原始数据,再根据当前状态决定展示排序后的数据还是原始数据。
步骤1:添加原始数据变量
// 保存未排序的原始通知数据 originalNotifications: any[] = []; // 标记当前是否处于排序状态 isSortByDateEnabled = false;
步骤2:修改getAllNotifications()方法
拉取数据时同时保存原始副本,然后根据排序状态决定展示哪份数据:
getAllNotifications() { // 这里假设你是从API拉取数据 this.api.fetchNotifications().subscribe(data => { // 保存原始数据副本 this.originalNotifications = [...data]; // 根据当前排序状态,决定展示排序后的数据还是原始数据 if (this.isSortByDateEnabled) { this.notification = [...this.originalNotifications].sort((a, b) => { return this.getTime(new Date(a.datetime_device)) - this.getTime(new Date(b.datetime_device)); }); } else { this.notification = [...this.originalNotifications]; } }); }
步骤3:修改排序触发函数
点击复选框时切换状态,同时更新展示的数据:
public sortbydate() { this.isSortByDateEnabled = !this.isSortByDateEnabled; if (this.isSortByDateEnabled) { // 展示排序后的数据 this.notification = [...this.originalNotifications].sort((a, b) => { return this.getTime(new Date(a.datetime_device)) - this.getTime(new Date(b.datetime_device)); }); } else { // 展示原始数据 this.notification = [...this.originalNotifications]; } }
这个方法的好处是不会原地修改原始数组,切换状态时更灵活,也避免了重复写排序逻辑。
关键提醒
- 不管用哪种方法,核心都是把排序操作和数据更新操作拆解开,不让数据一更新就自动排序。
- 注意
Array.sort()是原地修改数组的,如果需要保留原始数据,记得用扩展运算符[...array]创建副本后再排序,避免污染原始数据。
内容的提问来源于stack exchange,提问作者user9515832
相关产品推荐
相关产品推荐

