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

Ionic 3组件重复调用致SQL查询无限执行问题求助

Fixing Infinite SQL Query Execution in Ionic 3 Component

It sounds like you're running into infinite SQL query execution because you might be triggering database calls directly from your template (e.g., via a method called in *ngFor), which gets re-run on every Angular change detection cycle. Additionally, your initial date fetching uses a SQLResultSetRowList instead of a proper array, which can cause unexpected change detection behavior. Let's fix this step by step.

Root Cause

If you were calling a method like getRecords(date) from your template to fetch records for each date, Angular will execute that method every time it runs change detection (which happens frequently). This creates an infinite loop: the method runs a query, updates the component state, triggers change detection, and the method runs again.

Solution: Fetch All Data Once in the Component Lifecycle

Instead of querying the database from the template, fetch all necessary data in ionViewDidLoad (which runs once when the view loads), structure it into a usable format, and then reference that data in your template.

Step 1: Update the Component Class (report.ts)

First, we'll fetch distinct dates, then fetch records for each date, and store everything in component properties. We'll use promises to handle the async flow:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { SqlProvider } from '../../providers/sql/sql'; // Adjust import path as needed

@Component({
  selector: 'page-report',
  templateUrl: 'report.html'
})
export class ReportPage {
  dates: string[] = [];
  dateRecords: { [key: string]: any[] } = {}; // Maps date strings to their records

  constructor(public navCtrl: NavController, private sql: SqlProvider) {}

  ionViewDidLoad() {
    // First, fetch all distinct dates
    this.sql.query("SELECT DISTINCT date FROM walkInRecord").then(dateResult => {
      const dateRows = dateResult.res.rows;
      const recordFetchPromises = [];

      // Convert date rows to an array and prepare record fetch promises
      for (let i = 0; i < dateRows.length; i++) {
        const date = dateRows.item(i).date;
        this.dates.push(date);

        // Add a promise to fetch records for this date
        recordFetchPromises.push(
          this.sql.query("SELECT * FROM walkInRecord WHERE date = ?", [date]).then(recordResult => {
            const records = [];
            for (let j = 0; j < recordResult.res.rows.length; j++) {
              records.push(recordResult.res.rows.item(j));
            }
            return { date, records };
          })
        );
      }

      // Wait for all record queries to complete
      Promise.all(recordFetchPromises).then(results => {
        results.forEach(({ date, records }) => {
          this.dateRecords[date] = records;
        });
      });
    });
  }
}

Step 2: Update the Template (report.html)

Now, reference the pre-fetched data in your template using *ngFor on the dates array and the grouped dateRecords object:

<ion-content padding>
  <ion-list>
    <!-- Loop through each unique date -->
    <ion-item-group *ngFor="let date of dates">
      <ion-item-divider color="light">
        <h2>Date: {{ date }}</h2>
      </ion-item-divider>

      <!-- Loop through records for this date -->
      <ion-item *ngFor="let record of dateRecords[date]">
        <p><strong>ID:</strong> {{ record.id }}</p>
        <p><strong>Name:</strong> {{ record.name }}</p>
        <!-- Add other fields from your walkInRecord table here -->
      </ion-item>
    </ion-item-group>
  </ion-list>
</ion-content>

Optimized Approach: Single Query + Client-Side Grouping

To reduce database calls (more efficient for large datasets), fetch all records at once and group them by date in code:

ionViewDidLoad() {
  this.sql.query("SELECT * FROM walkInRecord").then(allResult => {
    const allRecords = [];
    for (let i = 0; i < allResult.res.rows.length; i++) {
      allRecords.push(allResult.res.rows.item(i));
    }

    // Group records by date
    this.dateRecords = allRecords.reduce((groups, record) => {
      const date = record.date;
      if (!groups[date]) groups[date] = [];
      groups[date].push(record);
      return groups;
    }, {});

    // Get sorted distinct dates
    this.dates = Object.keys(this.dateRecords).sort((a, b) => new Date(b) - new Date(a));
  });
}

This approach uses one SQL query instead of N+1 queries (where N is the number of distinct dates), which is much more performant.

Key Takeaways

  • Never call async database methods directly from your template—they'll run infinitely on change detection.
  • Convert SQLResultSetRowList to a plain array for reliable *ngFor iteration.
  • Fetch and structure all data in component lifecycle hooks (like ionViewDidLoad) before rendering.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:53:18