完整的日历-可观察的传递事件数据-未显示在日历上

时间:2018-08-16 22:21:13

标签: angular rxjs fullcalendar observable behaviorsubject

我正在使用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"}

1 个答案:

答案 0 :(得分:2)

此方法唯一可行的方法是通过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