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

Ionic 5中API新增列表项后滑动手势失效问题求助

Fixing Ionic 5 Gesture API for Dynamically Added Cards

Hey there! I see the issue you're facing—when you add new cards to your people array, those fresh cards don't have the swipe gestures attached like your initial three. Let's break down why this happens and how to fix it.

The Root Cause

Your ngAfterViewInit method runs only once when the component first loads. That means you're only attaching gestures to the three initial cards. When you push a new user to people, Angular renders a new ion-card, but your code never binds the swipe gesture to this new element.

Step-by-Step Solution

Here's how to update your code so every new card gets the swipe functionality:

  1. Track existing gestures to avoid duplicate bindings
  2. Listen for changes to the card list so we can reattach gestures when new cards are added
  3. Fix minor code typos/errors that might cause unexpected behavior

Updated .ts Code

import { HttpClient } from '@angular/common/http';
import { AfterViewInit, Component, ElementRef, NgZone, QueryList, Renderer2, ViewChildren } from '@angular/core';
import { GestureController, IonCard,Gesture, Platform } from '@ionic/angular';

@Component({
 selector: 'app-userhome',
 templateUrl: './userhome.page.html',
 styleUrls: ['./userhome.page.scss'],
})
export class UserhomePage implements AfterViewInit {
 dt:any;
 new:any;
 @ViewChildren(IonCard,{read:ElementRef}) cards:QueryList<any>;
 longPressActive:Boolean;
 people = [
 { name:{ first:'Random Name' }, img:'https://picsum.photos/200', email:'random@email.com' },
 { name:{ first:'Cool Name' }, img:'https://picsum.photos/200', email:'random@email.com' },
 { name:{ first:'Name' }, img:'https://picsum.photos/200', email:'random@email.com' }
 ];
 // Store references to all active gestures to clean them up later
 private gestures: Gesture[] = [];

 constructor(
   public http:HttpClient,
   private gestureCtrl: GestureController, 
   private ngZone:NgZone,
   public renderer:Renderer2, 
   private plt :Platform
 ) { }

 async ngAfterViewInit(){
   // Set up initial card gestures
   this.setupCardGestures();

   // Listen for changes to the card list (triggers when new cards are added)
   this.cards.changes.subscribe(() => {
     this.setupCardGestures();
   });
 }

 private setupCardGestures() {
   // Destroy all existing gestures to avoid duplicate bindings
   this.gestures.forEach(gesture => gesture.destroy());
   this.gestures = [];

   const cardArray = this.cards.toArray();
   this.useTinderSwipe(cardArray);
 }

 useTinderSwipe(cardArray){
   for(let i=0;i<cardArray.length;i++){
     const card = cardArray[i];
     console.log('card: ',card);
     const gesture: Gesture = this.gestureCtrl.create({
       el: card.nativeElement,
       threshold: 15,
       gestureName: 'swipe', // Fixed typo from "siwpe" to "swipe"
       onStart:ev=>{
       },
       onMove:ev=>{
         card.nativeElement.style.transform = `translateX(${ev.deltaX}px) rotate(${ev.deltaX/10}deg)`;
       },
       onEnd:ev=>{
         // Fixed: Use transition instead of transform for animation timing
         card.nativeElement.style.transition = '3.5s ease-out';
         if(ev.deltaX > 150){
           card.nativeElement.style.transform = `translate(${+this.plt.width()*2}px) rotate(${ev.deltaX/2}deg)`;
           this.http.get('https://randomuser.me/api/').subscribe(res=>{
             this.dt = res;
             this.new = this.dt.results[0];
             this.people.push(this.new);
             console.log(this.dt.results[0]);
           })
         }else if(ev.deltaX < -150){
           card.nativeElement.style.transform = `translate(-${+this.plt.width()*2}px) rotate(${ev.deltaX/2}deg)`;
         }else {
           card.nativeElement.style.transform = '';
         }
       }
     }, true);
     gesture.enable(true);
     // Add the new gesture to our tracking array
     this.gestures.push(gesture);
   }
 }
}

Key Changes Explained

  • gestures array: Stores all active swipe gestures so we can destroy them before reattaching—this prevents multiple gestures from being bound to the same card, which would cause weird behavior.
  • setupCardGestures() method: Encapsulates the gesture initialization logic, making it easy to re-run whenever the card list changes.
  • cards.changes.subscribe(): Listens for Angular to add new ion-card elements to the DOM. When this happens, we re-run our gesture setup code to include the new cards.
  • Fixed typos: Corrected gestureName from "siwpe" to "swipe" and fixed the CSS transition property in onEnd.

Now, every time you swipe a card and add a new user to people, the new card will automatically have the swipe gesture attached just like your initial cards.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:32:56