打字稿:得到一个未定义的值

时间:2018-03-29 11:55:45

标签: string angular typescript undefined angular5

我似乎遇到了一个无法解决的问题。

我希望'dialogTitle'变量还在title变量旁边显示startHour和startMinute变量。但是,在标题之后,我似乎得到了两次冠军和'未定义'。我该怎么办?

事件form.component.ts

import { Component, Inject, ViewEncapsulation } from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';

import { MatColors } from '@fuse/mat-colors';

import { CalendarEvent } from 'angular-calendar';
import { CalendarEventModel } from '../event.model';

import { locale as eventFormEnglish } from './i18n/en';
import { locale as eventFormDutch } from './i18n/nl';

import { FuseCalendarComponent } from '../calendar.component';

@Component({
    selector     : 'fuse-calendar-event-form-dialog',
    templateUrl  : './event-form.component.html',
    styleUrls    : ['./event-form.component.scss'],
    encapsulation: ViewEncapsulation.None
})

export class FuseCalendarEventFormDialogComponent
{
    event: CalendarEvent;
    dialogTitle: string;
    eventForm: FormGroup;
    action: string;
    startHour: string;
    startMinute: string;
    endHour: string;
    endMinute: string;
    presetColors = MatColors.presets;

    //Shows dropdown items

    startTimeHours = [
        {value: 'time-0', viewValue: '7'},
        {value: 'time-1', viewValue: '8'},
        {value: 'time-2', viewValue: '9'},
        {value: 'time-3', viewValue: '10'},
        {value: 'time-4', viewValue: '11'},
        {value: 'time-5', viewValue: '12'},
        {value: 'time-6', viewValue: '13'},
        {value: 'time-7', viewValue: '14'},
        {value: 'time-8', viewValue: '15'},
        {value: 'time-9', viewValue: '16'},
        {value: 'time-10', viewValue: '17'},
        {value: 'time-11', viewValue: '18'},
        {value: 'time-12', viewValue: '19'},
        {value: 'time-13', viewValue: '20'},
        {value: 'time-14', viewValue: '21'},
        {value: 'time-15', viewValue: '22'},
        {value: 'time-16', viewValue: '23'}
    ];
    startTimeMinutes = [
        {value: 'time-0', viewValue: '0'},
        {value: 'time-1', viewValue: '5'},
        {value: 'time-2', viewValue: '10'},
        {value: 'time-3', viewValue: '15'},
        {value: 'time-4', viewValue: '20'},
        {value: 'time-5', viewValue: '25'},
        {value: 'time-6', viewValue: '30'},
        {value: 'time-7', viewValue: '35'},
        {value: 'time-8', viewValue: '40'},
        {value: 'time-9', viewValue: '45'},
        {value: 'time-10', viewValue: '50'},
        {value: 'time-11', viewValue: '55'}
    ];

    endTimeHours = [
        {value: 'time-0', viewValue: '7'},
        {value: 'time-1', viewValue: '8'},
        {value: 'time-2', viewValue: '9'},
        {value: 'time-3', viewValue: '10'},
        {value: 'time-4', viewValue: '11'},
        {value: 'time-5', viewValue: '12'},
        {value: 'time-6', viewValue: '13'},
        {value: 'time-7', viewValue: '14'},
        {value: 'time-8', viewValue: '15'},
        {value: 'time-9', viewValue: '16'},
        {value: 'time-10', viewValue: '17'},
        {value: 'time-11', viewValue: '18'},
        {value: 'time-12', viewValue: '19'},
        {value: 'time-13', viewValue: '20'},
        {value: 'time-14', viewValue: '21'},
        {value: 'time-15', viewValue: '22'},
        {value: 'time-16', viewValue: '23'}
    ];
    endTimeMinutes = [
        {value: 'time-0', viewValue: '0'},
        {value: 'time-1', viewValue: '5'},
        {value: 'time-2', viewValue: '10'},
        {value: 'time-3', viewValue: '15'},
        {value: 'time-4', viewValue: '20'},
        {value: 'time-5', viewValue: '25'},
        {value: 'time-6', viewValue: '30'},
        {value: 'time-7', viewValue: '35'},
        {value: 'time-8', viewValue: '40'},
        {value: 'time-9', viewValue: '45'},
        {value: 'time-10', viewValue: '50'},
        {value: 'time-11', viewValue: '55'}
    ];

    constructor(
        public dialogRef: MatDialogRef<FuseCalendarEventFormDialogComponent>,
        @Inject(MAT_DIALOG_DATA) private data: any,
        private formBuilder: FormBuilder
    )
    {
        this.event = data.event;
        this.action = data.action;

        if ( this.action === 'edit' )
        {
            this.dialogTitle = this.event.title + " - " + this.startHour + ":" + this.startMinute;
        }
        else
        {
            this.dialogTitle = 'New Event';
            this.event = new CalendarEventModel({
                start: data.date,
                end  : data.date
            });
        }

        this.eventForm = this.createEventForm();
    }

    createEventForm()
    {
        return new FormGroup({
            title       : new FormControl(this.event.title),
            start       : new FormControl(this.event.start),
            end         : new FormControl(this.event.end),
            startHour   : new FormControl(this.startHour),
            startMinute : new FormControl(this.startMinute),
            endHour     : new FormControl(this.endHour),
            endMinute   : new FormControl(this.endMinute),
            allDay      : new FormControl(this.event.allDay),
            color       : this.formBuilder.group({
                primary     : new FormControl(this.event.color.primary),
                secondary   : new FormControl(this.event.color.secondary)
            }),
            meta        :
                this.formBuilder.group({
                    location: new FormControl(this.event.meta.location),
                    notes   : new FormControl(this.event.meta.notes)
                })
        });
    }
}

事件form.component.html

<div class="dialog-content-wrapper">
    <mat-toolbar matDialogTitle class="mat-accent m-0">
        <div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
            <span class="title dialog-title">{{dialogTitle}}</span>
            <button mat-button class="mat-icon-button"
                    (click)="dialogRef.close()"
                    aria-label="Close dialog">
                <mat-icon>close</mat-icon>
            </button>
        </div>
    </mat-toolbar>

    <div mat-dialog-content class="p-24 m-0" fusePerfectScrollbar>

        <form name="eventForm" [formGroup]="eventForm" class="event-form w-100-p" fxLayout="column" fxFlex>

            <mat-form-field class="w-100-p">
                <input matInput
                       name="title"
                       formControlName="title"
                       [placeholder]="'FORM.TITLE' | translate"
                       required>
            </mat-form-field>

            <div class="py-16" fxFlex="1 0 auto" fxLayout="row">
                <mat-slide-toggle
                    name="allDay"
                    formControlName="allDay"
                    class="mr-24"
                    aria-label="All day">
                    {{ 'FORM.ALLDAY' | translate }}
                </mat-slide-toggle>
            </div>

            <div class="py-16" fxFlex="1 0 auto" fxLayout="column" fxLayout.gt-xs="row" formGroupName="color">

                <mat-form-field class="mr-sm-24" fxFlex>
                    <input matInput
                           class="primary-color-input"
                           name="primary color"
                           formControlName="primary"
                           [placeholder]="'FORM.PRIMARYCOLOR' | translate"
                           [(colorPicker)]="event.color.primary"
                           cpWidth="290px"
                           [cpPresetColors]="presetColors"
                           [style.background]="event.color.primary"
                           (colorPickerChange)="event.color.primary = $event; eventForm.patchValue({color:{primary:$event}})"/>
                </mat-form-field>

                <mat-form-field fxFlex>
                    <input matInput
                           class="secondary-color-input"
                           name="secondary color"
                           formControlName="secondary"
                           [placeholder]="'FORM.SECONDARYCOLOR' | translate"
                           [(colorPicker)]="event.color.secondary"
                           cpWidth="290px"
                           [cpPresetColors]="presetColors"
                           [style.background]="event.color.secondary"
                           (colorPickerChange)="event.color.secondary = $event; eventForm.patchValue({color:{secondary:$event}})"/>
                </mat-form-field>

            </div>

            <div fxFlex="1 0 auto" fxLayout="column" fxLayout.gt-xs="row">

                <mat-form-field class="mr-sm-24" fxFlex>
                    <input matInput [matDatepicker]="startDatePicker" [placeholder]="'FORM.STARTDATE' | translate"
                           name="start"
                           formControlName="start" required>
                    <mat-datepicker-toggle matSuffix [for]="startDatePicker"></mat-datepicker-toggle>
                    <mat-datepicker #startDatePicker></mat-datepicker>
                </mat-form-field>

                <mat-form-field>
                  <mat-select [placeholder]="'FORM.STARTHOUR' | translate" formControlName="startHour" required>
                        <mat-option *ngFor="let startTimeHour of startTimeHours" [value]="startTimeHour">
                          {{startTimeHour.viewValue}}
                        </mat-option>
                    </mat-select>
                </mat-form-field>

                <mat-form-field>
                  <mat-select [placeholder]="'FORM.STARTMINUTE' | translate" formControlName="startMinute" required>
                        <mat-option *ngFor="let startTimeMinute of startTimeMinutes" [value]="startTimeMinute">
                          {{startTimeMinute.viewValue}}
                        </mat-option>
                    </mat-select>
                </mat-form-field>

            </div>

            <div fxFlex="1 0 auto" fxLayout="column" fxLayout.gt-xs="row">

                <mat-form-field class="mr-sm-24" fxFlex>
                    <input matInput [matDatepicker]="endDatePicker" [placeholder]="'FORM.ENDDATE' | translate"
                           name="end"
                           formControlName="end" required>
                    <mat-datepicker-toggle matSuffix [for]="endDatePicker"></mat-datepicker-toggle>
                    <mat-datepicker #endDatePicker></mat-datepicker>
                </mat-form-field>

                <mat-form-field>
                  <mat-select [placeholder]="'FORM.ENDHOUR' | translate" formControlName="endHour" required>
                        <mat-option *ngFor="let endTimeHour of endTimeHours" [value]="endTimeHour">
                          {{endTimeHour.viewValue}}
                        </mat-option>
                    </mat-select>
                </mat-form-field>

                <mat-form-field>
                  <mat-select [placeholder]="'FORM.ENDMINUTE' | translate" formControlName="endMinute" required>
                        <mat-option *ngFor="let endTimeMinute of endTimeMinutes" [value]="endTimeMinute">
                          {{endTimeMinute.viewValue}}
                        </mat-option>
                    </mat-select>
                </mat-form-field>

            </div>

            <mat-form-field formGroupName="meta" class="w-100-p">
                <input matInput
                       name="location"
                       formControlName="location"
                       [placeholder]="'FORM.LOCATION' | translate">
            </mat-form-field>

            <mat-form-field formGroupName="meta" class="w-100-p">

                <textarea matInput
                          formControlName="notes"
                          [placeholder]="'FORM.NOTES' | translate"
                          mat-maxlength="250"
                          max-rows="4">
                </textarea>
            </mat-form-field>

        </form>

    </div>

    <div mat-dialog-actions class="m-0 p-16" fxLayout="row" fxLayoutAlign="space-between center">

        <button *ngIf="action !=='edit'"
                mat-raised-button
                (click)="dialogRef.close(eventForm)"
                class="save-button mat-accent"
                [disabled]="eventForm.invalid"
                aria-label="SAVE">
            SAVE
        </button>

        <button *ngIf="action ==='edit'"
                mat-raised-button
                (click)="dialogRef.close(['save',eventForm])"
                class="save-button mat-accent"
                [disabled]="eventForm.invalid"
                aria-label="SAVE">
             {{ 'FORM.SAVE' | translate }}
        </button>

        <button *ngIf="action ==='edit'"
                mat-button
                class="mat-icon-button"
                (click)="dialogRef.close(['delete',eventForm])"
                aria-label="Delete"
                matTooltip="Delete">
            <mat-icon>delete</mat-icon>
        </button>
    </div>
</div>

我认为这与我没有以正确的方式或类似的方式宣布这两个变量的事实有关,但我有点新,所以我不确定我在这里做错了什么。这是订单吗?

编辑:它应该从数据库条目中获取startHour和startMinute变量,但我不知道如何。数据库在另一个文件中声明:

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: string; meta: Object; location: string; notes: string; start: string; title: string; }
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>;

    vehicle = [
        {value: 'vehicle-0', viewValue: 'Test 1'},
        {value: 'vehicle-1', viewValue: 'Test 2'}
    ]

    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 => {
            const data = a.payload.doc.data() as Ride;
            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();
    }

    setEvents()
    {
        //set this.events
//        this.events = this.ridesCollection.add(rides);
    }

    /**
     * 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
            {
                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.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
            }
        });

//        console.log(event);

        this.dialogRef.afterClosed()
            .subscribe(response => {
                if ( !response )
                {
                    return;
                }
                const actionType: string = response[0];
                const formData: FormGroup = response[1];
                switch ( actionType )
                {
                    /**
                     * Save
                     */
                    case 'save':
                        var 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);
                        this.ridesDocument.set(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);
                this.ridesCollection.add(newEvent);
            });
    }
}

提前致谢!

2 个答案:

答案 0 :(得分:1)

您似乎没有向startHourstartMinute提供任何值。你在哪里

startHour: string
startMinute: string

您只是声明这些变量是字符串类型,但没有给它们一个值。如果你想给它们一个值,你可以在同一点分配一个值,如下所示:

startHour: string = 'value'
startMinute: string = 'value'

或在您的构造函数中,在您使用它们之前

this.event = data.event;
this.action = data.action;

this.startHour = 'value';
this.startMinute = 'value';

if ( this.action === 'edit' )
{
  this.dialogTitle = this.event.title + " - " + this.startHour + ":" + this.startMinute;
}

希望这有帮助并祝你好运!

答案 1 :(得分:0)

宣言和定义是两回事。

startHour: string; // This is just declaring a variable. We haven't defined any value for it.
console.log(this.startHour); // will give undefined.

startHour: string = '';  //This is declaring + defining the variable.
console.log(this.startHour); // will give any emppty string.