Приложение Angular / Firebase продолжает показывать данные с предыдущей страницы - PullRequest
2 голосов
/ 06 августа 2020

У меня есть приложение Angular с домашней страницей, где я показываю 4 последних строки в коллекции Firebase «транзакции» (упорядоченные по дате в порядке убывания). Затем есть отдельная страница транзакций, на которой я показываю первые 10 строк в этой коллекции (отсортированные по сумме в порядке убывания). Однако, когда я начинаю с домашней страницы, а затем go на страницу транзакций, на моей гистограмме, которая должна отображать 10 самых крупных транзакций по сумме, я все еще вижу четыре последних транзакции с домашней страницы.

Ссылка на демонстрацию: https://tickrs-app.web.app/

Шаги для воспроизведения:

  1. откройте демонстрационное приложение
  2. на главной странице в самом низу вы увидите «Последние транзакции»
  3. откройте меню и перейдите на страницу «Транзакции»
  4. гистограмма будет иметь вид немного странно, кажется, что данные все еще содержат 4 недавних транзакции с домашней страницы
  5. перейдите на другую страницу (не на домашнюю страницу), а затем вернитесь на страницу «Транзакции», гистограмма должна выглядеть нормально сейчас

Вот мой код для home.page.ts :

  // Function to load the 4 most recent transactions to show on the home page
  async loadData() {
    // Order by date, descending
    const orderParamsDateDesc = {
      field: 'date',
      order: 'desc'
    }
    
    // Call our service to load the data, given the ordering details, and limit the number of rows to 4
    await this._FirebaseService.readSortLimit('transactions', orderParamsDateDesc, 4).then(result => this.transactionRows = result);
  }

  async ngOnInit() {
    // Only try to load the data if the user is authenticated again
    this.afAuth.onAuthStateChanged(async () => {
      await this.loadData();
    })
  }

Вот тот же код для transaction.page.ts :

  // Function to load the top 10 transactions, ordered by amount (descending)
  async getRows() {
    // Initialize the arrays
    this.barChartDataEur = [];
    this.barChartLabelsEur = [];
    let rows: any = [];

    // Order by amount, descending
    let orderParams = {
      field: 'amount',
      order: 'desc'
    }

    // Call our service to load the data given the ordering details, and limit the number of rows to 10
    await this._FirebaseService.readSortLimit("transactions", orderParams, 10).then(result => rows = result);

    // Loop over the resulting rows and load the stock tickers and amount separately in the arrays which will be used for the bar chart
    await rows.forEach(row => {
      this.barChartLabelsEur.push(row.ticker.slice(0, 8));
      this.barChartDataEur.push(row.amount);
    });

    // Set the loaded flag to true
    this.loaded = true;
  }

  ngOnInit() {
    // Only execute this part if user is authenticated
    this.afAuth.onAuthStateChanged(async () => {
      this.getRows();
    })
  }

Вот часть transaction.page. html для рендеринга гистограмма:

  <div class="chart-canvas">
    <canvas baseChart *ngIf="loaded"  // Only if data is loaded
            [data]="barChartDataEur"
            [labels]="barChartLabelsEur"
            [chartType]="barChartType"
            [options]="barChartOptions"
            [colors]="barChartColors"
            [legend]="barChartLegend"
            [plugins]="barChartPlugins">
    </canvas>
  </div>

Вот мой firebase.service.ts с функцией readSortLimit, которая используется на обеих страницах:

  // Input: name of the Firebase collection, the ordering details and the number of rows to return
  readSortLimit(collection, orderDetails, limitNumber) {
    return new Promise((resolve, reject) => {
      let result = [];
      this.firestore
        .collection(collection, ref => ref
          .orderBy(orderDetails.field, orderDetails.order)
          .limit(limitNumber)
        )
        .snapshotChanges()
        .subscribe(item => {
          Array.from(item).forEach(row => {
            result.push(row.payload.doc.data());
          });
          resolve(result);
        });
    });
  }

1 Ответ

0 голосов
/ 16 августа 2020

snapshotChanges вероятно, сначала обрабатывает и возвращает данные из кеша в качестве быстрого результата. Ваша функция readSortLimit возвращает обещание, и обещание разрешается с данными из кеша. Следующие resolve просто игнорируются.

Вам нужно изменить функцию readSortLimit, чтобы вместо этого возвращалось Observable.

  readSortLimit(collection, orderDetails, limitNumber) {
    return this.firestore
        .collection(collection, ref => ref
          .orderBy(orderDetails.field, orderDetails.order)
          .limit(limitNumber)
        )
        .snapshotChanges()
        .subscribe(items => {
          Array.from(items).map(row => row.payload.doc.data()));
        });
  }

А затем измените getRows

  async getRows() {
    // Order by amount, descending
    let orderParams = {
      field: 'amount',
      order: 'desc'
    }

    // Call our service to load the data given the ordering details, and limit the number of rows to 10
    this._FirebaseService.readSortLimit("transactions", orderParams, 10)
           .subscribe(rows => {
             // Initialize the arrays
             this.barChartDataEur = [];
             this.barChartLabelsEur = [];

             // Loop over the resulting rows and load the stock tickers and amount separately in the arrays which will be used for the bar chart
             rows.forEach(row => {
               this.barChartLabelsEur.push(row.ticker.slice(0, 8));
               this.barChartDataEur.push(row.amount);
             }); 
             
             // Set the loaded flag to true
             this.loaded = true;            
           });
  }

** Убедитесь, что getRows звонили не более одного раза. В противном случае вы будете подписаны на одно и то же событие несколько раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...