Ionic 5中API新增列表项后滑动手势失效问题求助
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:
- Track existing gestures to avoid duplicate bindings
- Listen for changes to the card list so we can reattach gestures when new cards are added
- 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
gesturesarray: 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 newion-cardelements to the DOM. When this happens, we re-run our gesture setup code to include the new cards.- Fixed typos: Corrected
gestureNamefrom "siwpe" to "swipe" and fixed the CSS transition property inonEnd.
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

