Listview for Nativescript 7

724 views Asked by At

Does the Listview work with Nativescript 7 with Angular I can still see it need tns-core modules?

I get a lot of errors on the nativescript-ui-listview ever since the upgrade. enter image description here

2

There are 2 answers

2
Robertino Vasilescu On

In NS7 you have to use @nativescript/core instead of tns-core which is kept for the retro compatibility.

Meaning you have to replace all tns-core occurrences with the @nativescript/core.

The ListView works.

0
Bott On

I got the RadListView to render but the swiping is not docking and the buttons not disappearing after the swipe. Here the versions I am working with whilst following some tutorial:

"dependencies": {
    "@angular/animations": "~11.0.0",
    "@angular/common": "~11.0.0",
    "@angular/compiler": "~11.0.0",
    "@angular/core": "~11.0.0",
    "@angular/forms": "~11.0.0",
    "@angular/platform-browser": "~11.0.0",
    "@angular/platform-browser-dynamic": "~11.0.0",
    "@angular/router": "~11.0.0",
    "@fortawesome/fontawesome-free": "^5.15.1",
    "@nativescript/angular": "~11.0.0",
    "@nativescript/core": "~7.1.0",
    "@nativescript/theme": "~3.0.0",
    "nativescript-toasty": "^3.0.0-alpha.2",
    "nativescript-ui-listview": "^9.0.4",
    "nativescript-ui-sidedrawer": "^9.0.3",
    "reflect-metadata": "~0.1.12",
    "rxjs": "^6.6.0",
    "zone.js": "~0.11.1"
  }

Like Robertino mentioned you will have to import from @nativescript/core rather than tns-core-modules. Check out the component file:

import { Component, OnInit, Inject, ViewChild } from '@angular/core';
import { FavoriteService } from '../services/favorite.service';
import { Dish } from '../shared/dish';
import { ListViewEventData, RadListView, SwipeActionsEventData } from 'nativescript-ui-listview';
import { RadListViewComponent } from 'nativescript-ui-listview/angular';
import { ObservableArray } from '@nativescript/core/data/observable-array';
import { View } from '@nativescript/core/ui/core/view';

import { confirm } from "@nativescript/core/ui";
import { ToastDuration, ToastPosition, Toasty } from 'nativescript-toasty';

@Component({
    selector: 'app-favorites',
    moduleId: module.id,
    templateUrl: './favorites.component.html',
    styleUrls: ['./favorites.component.css']
})
export class FavoritesComponent implements OnInit {

    favorites: ObservableArray<Dish>;
    errMess: string;

    @ViewChild('myListView') listViewComponent: RadListViewComponent;

    constructor(private favoriteservice: FavoriteService,
        @Inject('baseURL') private baseURL) {
    }

    ngOnInit() {
        this.favoriteservice.getFavorites()
            .subscribe(favorites => this.favorites = new ObservableArray(favorites),
                errmess => this.errMess = errmess);
    }

    deleteFavorite(id: number) {
        console.log('delete', id);

        let options = {
            title: "Confirm Delete",
            message: 'Do you want to delete Dish '+ id,
            okButtonText: "Yes",
            cancelButtonText: "No",
            neutralButtonText: "Cancel"
        };

        confirm(options).then((result: boolean) => {
            if(result) {

            this.favorites = null;

            this.favoriteservice.deleteFavorite(id)
                .subscribe(favorites => { 
                    const toast = new Toasty({
                        text:"Deleted Dish "+ id, 
                        duration: ToastDuration.SHORT, 
                        position: ToastPosition.BOTTOM
                    });
                    toast.show();
                    this.favorites = new ObservableArray(favorites);
                },
                errmess => this.errMess = errmess);
            }
            else {
            console.log('Delete cancelled');
            }
        });
    }

    public onCellSwiping(args: ListViewEventData) {
        var swipeLimits = args.data.swipeLimits;
        var currentItemView = args.object;
        var currentView;

        if(args.data.x > 200) {

        }
        else if (args.data.x < -200) {

        }
    }

    public onSwipeCellStarted(args: SwipeActionsEventData) {
        const swipeLimits = args.data.swipeLimits;
        const swipeView = args['object'];
        const leftItem = swipeView.getViewById<View>('mark-view');
        const rightItem = swipeView.getViewById<View>('delete-view');
        swipeLimits.left = leftItem.getMeasuredWidth();
        swipeLimits.right = rightItem.getMeasuredWidth();
        swipeLimits.threshold = leftItem.getMeasuredWidth()/2;
    }

    public onSwipeCellFinished(args: ListViewEventData) {

    }

    public onLeftSwipeClick(args: ListViewEventData) {
        console.log('Left swipe click');
        this.listViewComponent.listView.notifySwipeToExecuteFinished();
    }

    public onRightSwipeClick(args: ListViewEventData) {
        this.deleteFavorite(args.object.bindingContext.id);
        this.listViewComponent.listView.notifySwipeToExecuteFinished();
    }
}

Here is the template:

<ActionBar title="My Favorites" class="action-bar">
</ActionBar>
<StackLayout class="page">
    <RadListView #myListView [items]="favorites" *ngIf="favorites"
        selectionBehavior="none" (itemSwipeProgressEnded)="onSwipeCellFinished($event)"
        (itemSwipeProgressStarted)="onSwipeCellStarted($event)"
        (itemSwipeProgressChanged)="onCellSwiping($event)"
        swipeActions="true">
        <ListViewLinearLayout tkListViewLayout scrollDirection="vertical"
            itemInsertAnimation="Default" itemDeleteAnimation="Default">
        </ListViewLinearLayout>
        <ng-template tkListItemTemplate let-item="item">
            <StackLayout orientation="horizontal" class="listItemStackLayout">
                <Image row="0" col="0" rowSpan="2" height="60" width="60"
                    [src]="baseURL + item.image" class="thumb p-16"></Image>
                <GridLayout rows="auto, *" columns="*">
                    <Label row="0" col="0" [text]="item.name" class="labelName"></Label>
                    <Label row="1" col="0" [text]="item.description" class="labelText" textWrap="true"></Label>
                </GridLayout>
            </StackLayout>
        </ng-template>
        <GridLayout *tkListItemSwipeTemplate columns="auto, * , auto" class="listItemSwipeGridLayout">
            <StackLayout id="mark-view" class="markViewStackLayout" col="0"
                (tap)="onLeftSwipeClick($event)">
                <Label text="&#xf08d;" class="swipetemplateLabel fas"
                    verticalAlignment="center" horizontalAlignment="center"></Label>
            </StackLayout>
            <StackLayout id="delete-view" class="deleteViewStackLayout" col="2"
                (tap)="onRightSwipeClick($event)">
                <Label text="&#xf1f8;" class="swipetemplateLabel fas"
                    verticalAlignment="center" horizontalAlignment="center"></Label>
            </StackLayout>
        </GridLayout>
    </RadListView>
    <ActivityIndicator busy="true" *ngIf="!(favorites || errMess)" width="50"
        height="50" class="activity-indicator"></ActivityIndicator>
    <Label *ngIf="errMess" [text]="'Error: ' + errMess"></Label>

</StackLayout>

And the css class:

.listItemStackLayout {
    background-color: white;
    padding: 10;
}

.labelName {
    font-size: 20;
    font-weight: bold;
    margin-bottom: 8;
    margin-left: 16;
}

.labelTitle {
    font-size: 14;
    font-weight: bold;
}

.labelText {
    font-size: 12;
    margin-left: 16;
}

.markViewStackLayout {
    background-color: blue;
    padding: 16;
}

.deleteViewStackLayout {
    background-color: red;
    padding: 16;
}

.listItemSwipeGridLayout {
    background-color: white;
}

.swipetemplateLabel {
    size: 20;
    font-size: 28;
    color: white;
}

There are a few lines of code you may have to remove for things to work on your end.