ионный жест перестает работать при добавлении данных из вызовов API, возможно, проблема жизненного цикла? ( угловой )

#angular #api #ionic-framework #swipe #gesture

Вопрос:

Я пытаюсь реализовать свайп, подобный tinder, на ионной/угловой ионной карте в html с помощью ngFor, и создать жест viewchild в page.ts.

Мне удается заставить его работать с данными, которые я жестко закодирую в page.ts, но когда я пытаюсь извлечь данные из бд с помощью вызовов API, он больше не работает. Я попробовал то, что я обычно делаю что-загрузить результат моего вызова API в переменную, которую я использую в моем ngFor — но при этом содержание ионов-карта становится «неопределенным» я попытался толкая полученный контент в предварительно возбуждено переменной (в основном добавляя к жестко переменной), это работает, как я могу увидеть что-то новое на карты, но когда я достигаю карта для нового контента (путем считывания карты до), жест больше не работаю на нем, в основном застряли…

Какая-нибудь помощь, пожалуйста?

Вот выдержка из моего кода :

HTML-часть:

 <ion-content class="ion-padding">


<ion-card *ngFor="let q of itemListData; let index=index" [ngStyle]="{ zIndex: Questions.length - 5 - index, transform: 'scale('   (20 - index) / 20   ') translateY(-'   20 * index   'px)' }">
  <ion-card-header>
    <div class="progress"></div>
  </ion-card-header>
  <ion-card-content>
    <div class="inner-wrap">
      <p>
        Question of {{q.profileName}}<br>{{q.countRespondants}} respondants
      </p>        
      <h2>
        {{q.text}}
      </h2>
    </div>
  </ion-card-content>
</ion-card>

</ion-content>
 

Страница.ts:

 import { AfterViewInit, Component, ElementRef, NgZone, OnInit, QueryList, ViewChildren } from '@angular/core';
import { Gesture, GestureController, IonCard, Platform } from '@ionic/angular';
import { HttpConfigService } from '../services/http-config.service';
import { PollsList } from '../models/pollsList';
import { AuthService } from  '../auth/auth.service';
import { Router } from  "@angular/router";
import { AlertController } from '@ionic/angular';
import { connectableObservableDescriptor } from 'rxjs/internal/observable/ConnectableObservable';
import { ThrowStmt } from '@angular/compiler';

@Component({
  selector: 'app-swiper',
  templateUrl: './swiper.page.html',
  styleUrls: ['./swiper.page.scss'],
})
export class SwiperPage implements AfterViewInit {

    itemListData : PollsList[];
    itemListFollowsData = [];
    scrollLength = 0;
    page_number = 1;
    page_limit = 30;
    searchContent: string ="*";
    user = [];
    url: any;


  @ViewChildren (IonCard, {read: ElementRef}) cards: QueryList <ElementRef>;


  constructor(private gestureCtrl: GestureController, 
              private zone : NgZone, 
              private platform: Platform,
              private httpConfigService: HttpConfigService,
              public modalController: ModalController,
              public alertController: AlertController,
              private authService:  AuthService,
              private router: Router) { 

                this.itemListData = [];
                this.page_number=0;
              }

  ngOnInit() {
  }

  ionViewWillEnter () {

  this.pollInit();

  }

  ngAfterViewInit() {

     const cardArray = this.cards.toArray();
     this.setGesture(cardArray);  

  }

  setGesture(cards) {

    for (let c = 0; c < cards.length; c  ) {

      const card = cards[c];

      const gesture = this.gestureCtrl.create({
        el: card.nativeElement,
        gestureName: 'swipe',
        onStart: ev => {

        },
        onMove: ev => {
          card.nativeElement.style.transform = `translateX(${ev.deltaX}px) rotate(${ev.deltaX / 10}deg)`;
        },
        onEnd: ev => {
          card.nativeElement.style.transition = '.2s ease-out';
          if (ev.deltaX > this.platform.width() / 2.25) {

            card.nativeElement.style.transform = `translateX(${this.platform.width() * 3}px) rotate(${ev.startX / 2}deg)`;
            
          } else if (ev.deltaX < -this.platform.width() / 2.25) {
            card.nativeElement.style.transform = `translateX(-${this.platform.width() * 3}px) rotate(${ev.startX / 2}deg)`;
           
          } else {
            card.nativeElement.style.transform = '';
          }

        }
      });

      gesture.enable(true);

    }

  }

  pollInit(){
    this.url = '?pollText=aamp;offset='   this.page_number   'amp;limit=5';
    const temporary = this.httpConfigService.getListItemsAwait
    for (let i = 0; i < temporary.length; i  ) {
      this.itemListData.push(temporary[i]);
    }
    this.page_number = this.page_number 5
  } 

}
 

Ответ №1:

Вы могли бы попытаться повысить производительность, изменив способ выполнения запроса. вместо повторения 2 раза (в шаблоне и в самом запросе) вы можете использовать асинхронный канал и сохранить запрос в наблюдаемом

Просто установите itemListData : PollsList[]; в качестве наблюдаемого и передайте ему возврат вашего метода запроса:

   pollInit(){
    this.url = '?pollText=aamp;offset='   this.page_number   'amp;limit=5';
    this.itemListData = this.httpConfigService.getListItemsAwait
    this.page_number = this.page_number 5
  } 
 

и в html

 <ion-card *ngFor="let q of itemListData | async; let index=index" [ngStyle]="{ zIndex: Questions.length - 5 - index, transform: 'scale('   (20 - index) / 20   ') translateY(-'   20 * index   'px)' }">
  <ion-card-header>
    <div class="progress"></div>
  </ion-card-header>
  <ion-card-content>
    <div class="inner-wrap">
      <p>
        Question of {{q.profileName}}<br>{{q.countRespondants}} respondants
      </p>        
      <h2>
        {{q.text}}
      </h2>
    </div>
  </ion-card-content>
</ion-card>

</ion-content>