Ionic - Horizontal scroll tab for Categories [dupl

2020-01-25 06:52发布

问题:

I am working on a web/mobile application with mobile and we have this horizontal scroll tab at the above that represents Categories. On mobile it is fine, but on web I am required to add 2 flashes one on the right side and one on the left side. When the user clicks on them the scroll should move to that direction.

<ion-scroll scrollX="true">
       <ion-segment [(ngModel)]="SelectedSubCategory">
         <ion-segment-button value="" (ionSelect)="SelectSubCategory('')">
                <h6>
                   All Groups
                 </h6>
         </ion-segment-button>
         <ion-segment-button value="{{item.CategoryId}}" (ionSelect)="SelectSubCategory(item.CategoryId)" *ngFor="let item of SubCategories">
            <h6 class="subcategorytext">
                {{item.CategoryName}}
            </h6>
         </ion-segment-button>
       </ion-segment>
     </ion-scroll>

Is it possible to achieve that?

回答1:

Event though this questions may be considered as a duplicate of another question, I'll still add this answer because I think there's a better way to handle the categories (at least, from the UI/UX point of view).

The end result would look like this:

Basically, we're using the Ionic slider component to show the categories, but showing up to 3 categories per slide.

View:

In the view we just need to add a toolbar with a row, that will include 3 columns inside: one for the left arrow, another one for the slider, and the last one for the right arrow. Please also notice that we're setting the slidesPerView="3" property in the ion-slides element.

<ion-header>
    <ion-navbar color="primary">
        <button ion-button menuToggle>
            <ion-icon name="menu"></ion-icon>
        </button>
        <ion-title>App Name</ion-title>
    </ion-navbar>
    <ion-toolbar>
        <ion-row class="filters">
            <ion-col class="col-with-arrow" (click)="slidePrev()" no-padding col-1>
                <ion-icon *ngIf="showLeftButton" name="arrow-back"></ion-icon>
            </ion-col>
            <ion-col no-padding col-10>
                <ion-slides (ionSlideDidChange)="slideChanged()" slidesPerView="3">
                    <ion-slide (click)="filterData(category.id)" *ngFor="let category of categories">
                        <p [class.selected]="selectedCategory?.id === category.id">{{ category.name }}</p>
                    </ion-slide>
                </ion-slides>
            </ion-col>
            <ion-col class="col-with-arrow" (click)="slideNext()" no-padding col-1>
                <ion-icon *ngIf="showRightButton" name="arrow-forward"></ion-icon>
            </ion-col>
        </ion-row>

    </ion-toolbar>
</ion-header>

Component code:

Then we just need to handle what to do when any category is selected, or when the current slide changes:

// Angular
import { Component, Injector, ViewChild } from '@angular/core';

// Ionic
import { IonicPage, Slides } from 'ionic-angular';

// Models
import { CategoryModel } from './../../models/category.model';

@Component({ ... })
export class HomePage {
    @ViewChild(Slides) slides: Slides;

    public selectedCategory: CategoryModel;
    public categories: Array<CategoryModel>;
    public showLeftButton: boolean;
    public showRightButton: boolean;

    constructor(public injector: Injector) { ... }

    // ...

    private initializeCategories(): void {

        // Select it by defaut
        this.selectedCategory = this.categories[0];

        // Check which arrows should be shown
        this.showLeftButton = false;
        this.showRightButton = this.categories.length > 3;
    }

    public filterData(categoryId: number): void {
        // Handle what to do when a category is selected
    }

    // Method executed when the slides are changed
    public slideChanged(): void {
        let currentIndex = this.slides.getActiveIndex();
        this.showLeftButton = currentIndex !== 0;
        this.showRightButton = currentIndex !== Math.ceil(this.slides.length() / 3);
    }

    // Method that shows the next slide
    public slideNext(): void {
        this.slides.slideNext();
    }

    // Method that shows the previous slide
    public slidePrev(): void {
        this.slides.slidePrev();
    }
}

Styles:

    .filters {

        ion-col {
            text-align: center;
            font-size: 1.6rem;
            line-height: 1.6rem;

            ion-icon {
                color: #ccc;
            }

            &.col-with-arrow {
                display: flex;
                justify-content: center;
                align-items: center;
            }
        }

        p {
            color: #fff;
            margin: 0;
            font-size: 1.6rem;
            line-height: 1.6rem;
        }

        .selected {
            font-weight: 700;
        }
    }