ionic-framework
ionic-framework copied to clipboard
bug: ion-item-sliding does not work if options are asynchronously added
Prerequisites
- [X] I have read the Contributing Guidelines.
- [X] I agree to follow the Code of Conduct.
- [X] I have searched for existing issues that already report this problem, without success.
Ionic Framework Version
- [ ] v4.x
- [ ] v5.x
- [X] v6.x
- [ ] Nightly
Current Behavior
Using a single item template rendering the content within a virtual list, using cdk virtual scroll viewport, works as expected. But if switching between two item templates, e.g. one used during load (like skeleton text) and then presenting actual content when loaded, makes the slider behave very strange.
Upon first load The first top most items (e.g. 25 first) cannot be slided at all, but the rest of the items slide as expected.
Upon using refresher The first top most items (e.g. 25 first) cannot be slided at all, and the rest slides out but does not stay there, they seem to get dismissed automatically.
Expected Behavior
Sliders are expected to present them selves and stay visible until dismissed.
Steps to Reproduce
Use two different item templates rendering the content within a virtual list, using cdk virtual scroll viewport. Present one, e.g. during a simulated load, and switch to another after a little while.
Code Reproduction URL
https://stackblitz.com/edit/ionic6-angular13-bat2vm-aghn1e
Ionic Info
Ionic:
Ionic CLI : 6.19.0 (C:\Users\joel.CORP\AppData\Roaming\npm\node_modules@ionic\cli) Ionic Framework : @ionic/angular 6.1.12 @angular-devkit/build-angular : 14.0.4 @angular-devkit/schematics : 13.3.5 @angular/cli : 14.0.4 @ionic/angular-toolkit : 6.1.0
Capacitor:
Capacitor CLI : 3.6.0 @capacitor/android : 3.6.0 @capacitor/core : 3.6.0 @capacitor/ios : 3.6.0
Utility:
cordova-res : 0.15.2 native-run : 1.5.0
System:
NodeJS : v14.17.5 (C:\Program Files\nodejs\node.exe) npm : 7.22.0 OS : Windows 10
Additional Information
No response
By the way...
It works if keeping the ion-item-options out of the item templates, moving them statically into the ion-item-sliding, but then it's no longer that flexible since you cannot define them dynamically from the outside in order to have a generic virtual list component that can render any item template with any sliding options.
This works, compared to the stackblitz sample, but not that flexible.
<ion-list>
<ion-item-sliding *cdkVirtualFor="let item of [].constructor(1000); let i = index">
<ng-container
*ngTemplateOutlet="
isLoading ? loadingTemplate : itemTemplate;
context: { $implicit: item, index: i }
"
>
</ng-container>
<!-- options moved here, instead of being part of #itemTemplate -->
<ion-item-options side="start">
<ion-item-option color="success" class="action">
<ion-icon name="checkmark-outline"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</ion-list>
<ng-template #loadingTemplate let-item>
<ion-item>
<ion-avatar slot="start">
<ion-skeleton-text animated></ion-skeleton-text>
</ion-avatar>
<ion-label>
<h3>
<ion-skeleton-text animated style="width: 50%"></ion-skeleton-text>
</h3>
<p>
<ion-skeleton-text animated style="width: 80%"></ion-skeleton-text>
</p>
</ion-label>
</ion-item>
</ng-template>
<ng-template #itemTemplate let-item let-index="index">
<ion-item>
<ion-icon slot="start" name="notifications-outline"></ion-icon>
<ion-label>
<h2>
{{ index }}
</h2>
</ion-label>
</ion-item>
</ng-template>
Thanks for the issue. The problem here is that when each ion-item-sliding
is initialized, it queries for the inner ion-item-options
elements: https://github.com/ionic-team/ionic-framework/blob/7b10fa6476c2c2896c6810c57b3160f8c8896faa/core/src/components/item-sliding/item-sliding.tsx#L217
No options exist on initial load because the loading template is rendered, not the options template. The item sliding component needs the options elements in order to set leftOptions
or rightOptions
: https://github.com/ionic-team/ionic-framework/blob/7b10fa6476c2c2896c6810c57b3160f8c8896faa/core/src/components/item-sliding/item-sliding.tsx#L237-L240
Since these options are never set, the gesture can never start: https://github.com/ionic-team/ionic-framework/blob/7b10fa6476c2c2896c6810c57b3160f8c8896faa/core/src/components/item-sliding/item-sliding.tsx#L265
The issue here is that ion-item-sliding
does not support dynamically added ion-item-options
. The issue is not caused by virtual scrolling, but dynamically adding ion-item-options
is a side effect of using virtual scrolling in this way.
The example app from this comment is also a clean demonstration of this bug: https://stackblitz.com/edit/angular-5mxvej?file=src%2Fmain.ts
If you change the dropdown at the top to something else, altering which items get options (due to the *ngIf
), you still can't slide the newly chosen items. Note that you can still slide the original items, but the options no longer render.
@amandaejohnston will it be resolved in upcoming release?
Same bug for Ionic v7.0.6
Details
<ion-list>
<ion-item-sliding>
<ion-item-options side="start" *ngIf="true">
<ion-item-option color="success">Bug!!!</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>left</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option>Favorite</ion-item-option>
<ion-item-option color="danger">Delete</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</ion-list>
This has been resolved via https://github.com/ionic-team/ionic-framework/pull/27572 and the fix will be available in a future release of Ionic. Thank you!
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.