【问题标题】:full calendar - passing event data from observable - not showing up on calendar完整日历 - 从 observable 传递事件数据 - 未显示在日历上
【发布时间】:2018-08-16 22:21:12
【问题描述】:

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

数据服务:

@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"}

【问题讨论】:

    标签: angular rxjs fullcalendar observable behaviorsubject


    【解决方案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>
    


    More Info

    【讨论】:

    • 谢谢,我会试试这个,让你知道!这很奇怪,因为在我更改使用 Behavior Subject 之前,我仍在订阅并获取相同格式的数据。不知道为什么这次不一样。
    • 还有其他几种方法可以使用值进行初始化,但不刷新就不会更新。这是我能找到让它实时更新的唯一方法。
    • 啊,我明白了。这很好用,谢谢。我会将此作为正确答案。
    猜你喜欢
    • 2020-07-15
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多