You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ionic 4剧集追踪应用:复选框状态管理与SQLite存储问题

修复剧集复选框状态异常并实现SQLite存储加载功能

我来帮你搞定这两个问题——复选框选中/取消时的数组异常,以及SQLite持久化存储已看状态的功能,咱们一步步来:


一、先修复复选框selected数组清空的问题

你的代码里有两个核心问题导致了取消选中时数组被清空:

1. 循环边界错误

checkAll函数里的循环条件用了i <= this.seasonepisodes.length,但数组索引是从0到length-1的,这个条件会让循环跑到不存在的数组下标,不仅可能报错,还会漏标/误标剧集。

2. 过滤条件不匹配

selectEpisode里用el.testID !== data.testID做过滤,但从TMDB获取的剧集对象根本没有testID属性,应该用剧集自带的id字段来匹配。当取消选中时,这个错误的条件会把所有元素都过滤掉,导致selected数组直接清空。

修复后的TS代码:

seasonepisodes: any[] = [];
selected: any[] = [];
// 假设你已经有获取seasondetails的逻辑,保留并优化
this.seasonepisodes = this.seasondetails?.episodes || [];

checkAll() {
  // 修正循环边界为 < length
  for(let i = 0; i < this.seasonepisodes.length; i++) {
    const episode = this.seasonepisodes[i];
    episode.checked = true;
    // 防止重复添加到selected数组
    if (!this.selected.some(item => item.id === episode.id)) {
      this.selected.push(episode);
    }
  }
  console.log(this.seasonepisodes);
}

selectEpisode(data) {
  if (data.checked) {
    // 避免重复添加
    if (!this.selected.some(item => item.id === data.id)) {
      this.selected.push(data);
    }
  } else {
    // 用正确的id字段过滤数组
    this.selected = this.selected.filter(el => el.id !== data.id);
  }
  console.log(this.selected);
  // 后面会在这里加SQLite存储逻辑
}

HTML部分可以保留原样,不过建议给episodes.checked做个初始化(比如在获取到剧集数组后,给每个元素默认加checked: false),避免ngModel报警告。


二、实现SQLite存储与加载已看状态

接下来咱们把复选框状态持久化到本地SQLite数据库,确保用户重启APP后状态不会丢失。

1. 先安装依赖

在项目根目录执行:

ionic cordova plugin add cordova-sqlite-storage
npm install @ionic-native/sqlite

2. 页面TS里的完整实现

首先导入SQLite并注入到组件:

import { SQLite, SQLiteObject } from '@ionic-native/sqlite/ngx';

constructor(private sqlite: SQLite) {}

private db: SQLiteObject;
// 假设你有当前节目ID和季数的变量(需要从页面跳转参数或接口获取)
showId: number;
seasonNumber: number;

// 初始化数据库
async initDB() {
  this.db = await this.sqlite.create({
    name: 'tv_tracker.db',
    location: 'default'
  });
  // 创建已看剧集表,用节目ID+季数+剧集ID做唯一键,避免重复存储
  await this.db.executeSql(`
    CREATE TABLE IF NOT EXISTS watched_episodes (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      episode_id INTEGER,
      show_id INTEGER,
      season_number INTEGER,
      UNIQUE(episode_id, show_id, season_number)
    )
  `, []);
}

// 页面进入时加载已看状态
async ionViewWillEnter() {
  await this.initDB();
  // 查询当前季的已看剧集ID
  const res = await this.db.executeSql(`
    SELECT episode_id FROM watched_episodes 
    WHERE show_id = ? AND season_number = ?
  `, [this.showId, this.seasonNumber]);

  const watchedIds = [];
  for (let i = 0; i < res.rows.length; i++) {
    watchedIds.push(res.rows.item(i).episode_id);
  }

  // 更新复选框状态和selected数组
  this.seasonepisodes.forEach(episode => {
    episode.checked = watchedIds.includes(episode.id);
    if (episode.checked && !this.selected.some(item => item.id === episode.id)) {
      this.selected.push(episode);
    }
  });
}

// 修改selectEpisode,加入存储逻辑
async selectEpisode(data) {
  if (data.checked) {
    if (!this.selected.some(item => item.id === data.id)) {
      this.selected.push(data);
    }
    // 插入到数据库(用INSERT OR IGNORE避免重复)
    await this.db.executeSql(`
      INSERT OR IGNORE INTO watched_episodes (episode_id, show_id, season_number)
      VALUES (?, ?, ?)
    `, [data.id, this.showId, this.seasonNumber]);
  } else {
    this.selected = this.selected.filter(el => el.id !== data.id);
    // 从数据库删除对应记录
    await this.db.executeSql(`
      DELETE FROM watched_episodes 
      WHERE episode_id = ? AND show_id = ? AND season_number = ?
    `, [data.id, this.showId, this.seasonNumber]);
  }
  console.log(this.selected);
}

关键注意点

  • showId和seasonNumber需要你从页面的跳转参数或者接口返回数据中获取,用来唯一标识当前的节目和季,避免不同节目/季的剧集ID冲突。
  • 每次获取到seasonepisodes后,记得给每个剧集对象初始化checked: false,避免ngModel绑定出错。

内容的提问来源于stack exchange,提问作者Gor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:05:17