Полный календарь - передача данных о событиях из наблюдаемого - не отображается в календаре
Я использую ap-fullcalendar для angular/typcript. У меня есть служба данных, где я получаю события для календаря из своей базы данных, оборачиваю данные в объект поведения, подписываюсь на них и превращаю их в наблюдаемую из другой функции. У меня есть служба данных, потому что у меня есть несколько подписок на одну и ту же наблюдаемую. В моем компоненте, где находится календарь, я подписываюсь на данные. Однако, по некоторым причинам, события не передаются должным образом в календарь и не будут отображаться. Я вручную ввел некоторые значения для событий, чтобы проверить, что календарь работает нормально, что он делает. Я вывел то, что я получаю от моего сервиса (показано ниже), и он выглядит хорошо. В чем может быть проблема?
Служба данных:
@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 ответ
Единственный способ, которым это работает, - это вызов через 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>