完整日历 - 从 observable 传递事件数据 - 不显示在日历上

full calendar - passing event data from observable - not showing up on calendar

我正在为 angular/typescript 使用 ap-fullcalendar。我有一个数据服务,我从我的数据库中获取日历的事件,我将数据包装在一个行为主题中并订阅它并使它成为另一个函数的可观察对象。我有一个数据服务,因为我对同一个可观察对象有多个订阅。在日历所在的组件中,我订阅了数据。但是,出于某种原因,事件没有正确传递到日历并且不会显示。我手动输入了一些事件值,以检查日历是否正常工作。我已经输出了我从服务中获得的信息(如下所示),看起来不错。可能是什么问题?

数据服务:

@Injectable()
export class SubjectEventsService {

  allData: EventSchema[] = new Array<EventSchema>();
  allData$: BehaviorSubject<EventSchema[]>;


  constructor(private afs : AngularFirestore) { 
    //Get subjectEvents collection on initialise
    this.subjectEventCollection = this.afs.collection('subjectEvents');
    this.getSubjectEvents();
  }


  getSubjectEvents(subjectFilter?:string){
    if(!this.allData$){
      this.allData$ = <BehaviorSubject<EventSchema[]>> new BehaviorSubject(new Array<EventSchema>());
      this.subjectEventCollection.valueChanges().pipe(
        map(res => {
          let result : EventSchema[] = [];
          res.map(subjectEvent => {
            let eventSchema : EventSchema[] = subjectEvent.eventData;
            eventSchema.forEach(event => {
              result.push(event as EventSchema);
            })
          })
          console.log(result);
          return result;
        }))
        .subscribe(events => {
          console.log(events);
          this.allData = events;
          console.log(this.allData);
          this.allData$.next(events);
        });
      }
    }

  subscribeToDataServiceGetSubjectEvents(): Observable<EventSchema[]> {
    console.log(this.allData$);
    return this.allData$.asObservable();
  }
}

主页组件(日历所在的位置):

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit{

  calendarOptions: any;
  displayEvent: any;
  @ViewChild(CalendarComponent) ucCalendar: CalendarComponent;
  name: string;
  subjectFilter: string;

  allData$: Observable<EventSchema[]>;

  constructor(private subjectEventsService: SubjectEventsService, private dialog: MatDialog) { }

  ngOnInit(){
    this.subjectEventsService.subscribeToDataServiceGetSubjectEvents().subscribe(data=>{
      let data$:any = data;
      console.log("fun");
      console.log(data);
      this.calendarOptions = {
        editable: true,
        eventLimit: false,
        header: {
          left: 'prev,next today',
          center: 'title',
          right: 'month,agendaWeek,agendaDay,listMonth'
        },
        events: data$,
        //WORKS FINE WITH THIS DATA ENTERED MANUALLY
        // [{
        //   end: "2018-08-13T19:00:00",
        //   price: 10,          
        //   start:"2018-08-13T17:00:00",
        //   title:"Forces"
        // }],
        eventClick: (calEvent, jsEvent, view) => {
          this.openDialog(calEvent);
          // console.log('Event: ' + calEvent.title);
          // console.log('View: ' + view.name);
        }
      };
    });    
  }
  }
}

订阅的输出(这是日历要求的可接受格式):

Array(4)
0:{end: "2018-08-13T19:00:00", price: 10, start: "2018-08-13T17:00:00", title: "Forces"}
1:{end: "2018-08-19T13:00:00", price: 10, start: "2018-08-19T11:00:00", title: "Energy"}
2:{end: "2018-08-15T20:00:00", price: 10, start: "2018-08-15T17:00:00", title: "Trigonometry"}
3:{end: "2018-08-25T11:00:00", price: 10, start: "2018-08-25T08:00:00", title: "Mechanics"}

唯一可行的方法是通过 ViewChild 调用。这两个关键部分是您订阅中的 this.calendar.fullCalendar('removeEvents');this.calendar.fullCalendar('addEventSource', events);,因此在您的实例中,这样的事情应该有效:

    @Component({
      selector: 'app-home',
      templateUrl: './home.component.html',
      styleUrls: ['./home.component.css']
    })
    export class HomeComponent implements OnInit{

        calendarOptions:Object = {
            editable: true,
            eventLimit: false,
            header: {
                left: 'prev,next today',
                center: 'title',
                right: 'month,agendaWeek,agendaDay,listMonth'
            },
            events: [],
            eventClick: (calEvent, jsEvent, view) => {
                this.openDialog(calEvent);
            }
        };
      displayEvent: any;
      @ViewChild(CalendarComponent) ucCalendar: CalendarComponent;
      name: string;
      subjectFilter: string;

      allData$: Observable<EventSchema[]>;

      constructor(private subjectEventsService: SubjectEventsService, private dialog: MatDialog) { }

      ngOnInit(){
        this.subjectEventsService.subscribeToDataServiceGetSubjectEvents().subscribe(data=>{
          this.ucCalendar.fullCalendar('removeEvents');
          this.ucCalendar.fullCalendar('addEventSource', data);
        });    
      }
      }
    }


我的测试项目(为了理智)


    export class CalComponent implements OnInit {
      @ViewChild('calendar') calendar;

      _events = new BehaviorSubject<Event[]>(EVENTS);
      events$ = this._events.asObservable();

      constructor(private http:HttpClient) { }

      ngOnInit() {
      }

      onCalendarInit(e:boolean) {
        if(e) {
          this.events$.subscribe((events) => {
            this.calendar.fullCalendar('removeEvents');
            this.calendar.fullCalendar('addEventSource', events);
          });
        }
      }

      count:number = 1;
      nextEvent() {
        this.count++;
        EVENTS.push({id: 10 + this.count, title: "Hello!", start: `2018-08-${this.count}`});
        this._events.next(EVENTS);
      }

      calendarOptions:Object = {
        height: '600px',
        fixedWeekCount : false,
        defaultDate: '2016-09-12',
        editable: true,
        eventLimit: true,
        events: [] //Nothing needed here
      };
    }

    interface Event {
      id?:number;
      title:string;
      start:string;
      end?:string;
    }

Html

    <button (click)="nextEvent()">Click for next event</button>
    <angular2-fullcalendar #calendar [options]="calendarOptions" (initialized)="onCalendarInit($event)"></angular2-fullcalendar>


More Info