Angular 5:如何按字母顺序对Observable进行排序?

时间:2018-04-12 12:26:33

标签: javascript firebase rxjs google-cloud-firestore angularfire2

我有一个问题我无法弄清楚:我想按字母顺序对Observable中的数据进行排序(我认为至少是这样)。

代码基本上做的是从Firestore获取数据并显示从事件标题栏内的数据库获取的startHour和startMinute变量。这很好。但是,它没有排序'标题'正常。不是按字母顺序对它们进行排序(例如,在早期时间,即在10:50之前的07:20,然后是13:05),它会根据数据库中显示的文档ID对其进行排序。所以基本上它可以成为07:20,然后是13:05,然后是10:50,这不是我想要的。

calendar.component.ts:

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Subject } from 'rxjs/Subject';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';

import { MatDialog, MatDialogRef } from '@angular/material';
import { startOfDay, isSameDay, isSameMonth } from 'date-fns';

import { CalendarEvent, CalendarEventAction, CalendarEventTimesChangedEvent, CalendarMonthViewDay } from 'angular-calendar';

import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
import { fuseAnimations } from '@fuse/animations';

import { FuseCalendarEventFormDialogComponent } from './event-form/event-form.component';
import { CalendarEventModel } from './event.model';

import 'rxjs/add/operator/map';

export interface Ride { allDay: boolean; color: Object; /*primary: string; secondary: string;*/ end: Date; meta: Object; location: string; notes: string; start: Date; title: string; draggable: boolean; }
export interface RideId extends Ride { id: string }

@Component({
    selector     : 'fuse-calendar',
    templateUrl  : './calendar.component.html',
    styleUrls    : ['./calendar.component.scss'],
    encapsulation: ViewEncapsulation.None,
    animations   : fuseAnimations
})
export class FuseCalendarComponent implements OnInit
{   
    view: string;
    viewDate: Date;
    events: CalendarEvent[];
    locale: string = 'nl';
    public actions: CalendarEventAction[];
    activeDayIsOpen: boolean;
    refresh: Subject<any> = new Subject();
    dialogRef: any;
    confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
    selectedDay: any;
    rides: Observable<RideId[]>;
    ride: Observable<Ride>;

    private ridesCollection: AngularFirestoreCollection<Ride>;
    private ridesDocument: AngularFirestoreDocument<Ride>;



    vehicles = [
        {value: 'vehicle-0', viewValue: 'Alle'},
        {value: 'vehicle-1', viewValue: 'Buurtmobiel Beuningen/Weurt'},
        {value: 'vehicle-2', viewValue: 'Buurtmobiel Ewijk/Winssen'}
    ];

    constructor(
        public dialog: MatDialog,
        private readonly db: AngularFirestore,
    )
    {
        this.view = 'month';
        this.viewDate = new Date();
        this.activeDayIsOpen = true;
        this.selectedDay = {date: startOfDay(new Date())};



        this.actions = [
            {
                label  : '<i class="material-icons s-16">edit</i>',
                onClick: ({event}: { event: CalendarEvent }): void => {
                    this.editEvent('edit', event);
                }
            },
            {
                label  : '<i class="material-icons s-16">delete</i>',
                onClick: ({event}: { event: CalendarEvent }): void => {
                    this.deleteEvent(event);
                }
            }
        ];

        /**
         * Get events from service/server
         */
         this.ridesCollection = db.collection<Ride>('rides');

         this.rides = this.ridesCollection.snapshotChanges().map(actions => {
            return actions.map(a => {
            let data = a.payload.doc.data() as Ride;
                data.draggable = true;
            const id = a.payload.doc.id;
            return { id, ...data };
      });       
    });

//        this.setEvents();
    }

    ngOnInit()
    {
        /**
         * Watch re-render-refresh for updating db
         */
//        this.refresh.subscribe(updateDB => {
//            // console.warn('REFRESH');
//            if ( updateDB )
//            {
//                // console.warn('UPDATE DB');
//                this.calendarService.updateEvents(this.events);
//            }
//        });

//        this.calendarService.onEventsUpdated.subscribe(events => {
//            this.setEvents();
//            this.refresh.next();
//        });

//        this.ridesDocument = this.db.doc('rides/id');
//        this.ride = this.ridesDocument.valueChanges();
    }

    /**
     * Before View Renderer
     * @param {any} header
     * @param {any} body
     */
    beforeMonthViewRender({header, body})
    {
        // console.info('beforeMonthViewRender');
        /**
         * Get the selected day
         */
        const _selectedDay = body.find((_day) => {
            return _day.date.getTime() === this.selectedDay.date.getTime();
        });

        if ( _selectedDay )
        {
            /**
             * Set selectedday style
             * @type {string}
             */
            _selectedDay.cssClass = 'mat-elevation-z3';
        }

    }

    /**
     * Day clicked
     * @param {MonthViewDay} day
     */
    dayClicked(day: CalendarMonthViewDay): void
    {
        const date: Date = day.date;
        const events: CalendarEvent[] = day.events;

        if ( isSameMonth(date, this.viewDate) )
        {
            if ( (isSameDay(this.viewDate, date) && this.activeDayIsOpen === true) || events.length === 0 )
            {
                this.activeDayIsOpen = false;
            }
            else
            {
                //Titlebar(s) that appear(s) when a day has been selected

                this.activeDayIsOpen = true;
                this.viewDate = date;
            }
        }
        this.selectedDay = day;
        this.refresh.next();
    }

    /**
     * Event times changed
     * Event dropped or resized
     * @param {CalendarEvent} event
     * @param {Date} newStart
     * @param {Date} newEnd
     */
    eventTimesChanged({event, newStart, newEnd}: CalendarEventTimesChangedEvent): void
    {
        event.start = newStart;
        event.end = newEnd;

//        console.warn('Dropped or resized', event);

        this.ridesDocument = this.db.doc('rides/' + event.id);
        console.log(event.start);
        console.log(newStart);
        this.ridesDocument.update(event);
        this.refresh.next(true);
    }

    /**
     * Delete Event
     * @param event
     */
    deleteEvent(ride)
    {
        this.confirmDialogRef = this.dialog.open(FuseConfirmDialogComponent, {
            disableClose: false
        });

        this.confirmDialogRef.componentInstance.confirmMessage = 'Are you sure you want to delete?';

        this.confirmDialogRef.afterClosed().subscribe(result => {
            if ( result )
            {
//                const eventIndex = this.events.indexOf(event);
//                this.events.splice(eventIndex, 1);
//                this.refresh.next(true);

            }
            this.confirmDialogRef = null;
        });

    }

    /**
     * Edit Event
     * @param {string} action
     * @param {CalendarEvent} event
     */
    editEvent(action: string, event: CalendarEvent)
    {
//        const eventIndex = this.events.indexOf(event);

        this.dialogRef = this.dialog.open(FuseCalendarEventFormDialogComponent, {
            panelClass: 'event-form-dialog',
            data      : {
                event : event,
                action: action
            }
        });

        this.dialogRef.afterClosed()
            .subscribe(response => {
                if ( !response )
                {
                    return;
                }
                const actionType: string = response[0];
                const formData: FormGroup = response[1];
                switch ( actionType )
                {
                    /**
                     * Save
                     */
                    case 'save':
                        let saveData: any;
//                        this.events[eventIndex] = Object.assign(this.events[eventIndex], formData.getRawValue());
                        this.refresh.next(true);

                        saveData = formData.getRawValue();
//                        saveData.start.setHours(saveData.startHour);
//                        saveData.start.setMinutes(saveData.startMinute);

                        this.ridesDocument = this.db.doc('rides/' + event.id);
                        saveData.start.setHours(saveData.startHour, saveData.startMinute);
                        saveData.end.setHours(saveData.endHour, saveData.endMinute);
                        this.ridesDocument.update(saveData);

                        break;
                    /**
                     * Delete
                     */
                    case 'delete':

//                        this.deleteEvent(event);
                        this.ridesDocument = this.db.doc('rides/' + event.id);
                        this.ridesDocument.delete();

                        break;
                }
            });
    }

    /**
     * Add Event
     */
    addEvent(): void
    {
        this.dialogRef = this.dialog.open(FuseCalendarEventFormDialogComponent, {
            panelClass: 'event-form-dialog',
            data      : {
                action: 'new',
                date  : this.selectedDay.date
            }
        });
        this.dialogRef.afterClosed()
            .subscribe((response: FormGroup) => {
                if ( !response )
                {
                    return;
                }
                const newEvent = response.getRawValue();
//                newEvent.actions = this.actions;
//                this.events.push(newEvent);
                this.refresh.next(true);
                newEvent.start.setHours(newEvent.startHour, newEvent.startMinute);
                newEvent.end.setHours(newEvent.endHour, newEvent.endMinute);
                this.ridesCollection.add(newEvent);
            });
    }
}

我尝试过使用管道,以及.sort()和orderBy,但它什么都不喜欢。也许我已经以错误的方式做到了,我不能说,所以我会对这个问题有所帮助。

我使用Fuse2和Angular 5.数据库是Angularfire2 Firestore。

任何帮助将不胜感激!

编辑:我不确定这是否有任何帮助,但我可以将.sort()放在这里:

this.rides = this.ridesCollection.snapshotChanges().map(actions => {
            return actions.map(a => {
            let data = a.payload.doc.data() as Ride;
                data.draggable = true;
            const id = a.payload.doc.id;
            return { id, ...data };
      }).sort(); // Can add .sort() here without an error, but nothing happens
    });

但正如评论所说,它什么也没做,每当我尝试在()之间放置一个参数时,我得到一条错误信息......

1 个答案:

答案 0 :(得分:1)

Firebase具有内置功能,可根据您的标准和方向进行排序。

对于firestore,您可以 look here ,对于实时数据库,您可以 look here

相关问题