前提・実現したいこと
カレンダーアプリを制作しており、日付ごとのページでイベント操作をできるようにしたいです。
補足情報(FW/ツールのバージョンなど)
カレンダーのライブラリー: ionic2-calendar
ionic info
Ionic: Ionic CLI : 5.2.5 (/usr/local/lib/node_modules/ionic) Ionic Framework : @ionic/angular 4.7.1 @angular-devkit/build-angular : 0.801.3 @angular-devkit/schematics : 8.1.3 @angular/cli : 8.1.3 @ionic/angular-toolkit : 2.0.0 Cordova: Cordova CLI : 9.0.0 (cordova-lib@9.0.1) Cordova Platforms : none Cordova Plugins : no whitelisted plugins (0 plugins total) Utility: cordova-res : 0.6.0 native-run : 0.2.8 System: NodeJS : v10.15.1 (/usr/local/bin/node) npm : 6.4.1 OS : macOS Mojave Xcode : Xcode 10.2.1 Build version 10E1001
参考にしたサイト:
発生している問題・エラーメッセージ
日付ごとにイベントを判別できない。
イベントのidをパラメーターとして渡すために以下のようにしました。
html
1<ion-header> 2 <ion-toolbar color="danger"> 3 <ion-buttons slot="start"> 4 <ion-menu-button></ion-menu-button> 5 </ion-buttons> 6 <ion-title> 7 {{ viewTitle }} 8 </ion-title> 9 <ion-buttons slot="end"> 10 <ion-button (click)="today()">Today</ion-button> 11 </ion-buttons> 12 </ion-toolbar> 13</ion-header> 14 15<ion-content padding> 16 17 <calendar [eventSource]="eventSource" 18 [calendarMode]="calendar.mode" 19 [currentDate]="calendar.currentDate" 20 (onCurrentDateChanged)="onCurrentDateChanged($event)" 21 (onEventSelected)="onEventSelected($event)" 22 (onTitleChanged)="onViewTitleChanged($event)" 23 (onTimeSelected)="onTimeSelected($event)" 24 [locale]="calendar.locale" 25 *ngFor="let dayEvent of (dayEvents | async)" 26 [routerLink]="['/day', dayEvent.id]" 27 > 28</calendar> 29 30<ion-list> 31 <ion-item *ngFor="let dayEvent of (dayEvents | async)"> 32 <!-- 全イベントのidが取れる --> 33 <p>{{ dayEvent.id }}</p> 34 </ion-item> 35</ion-list> 36</ion-content>
すると、イベントの数だけカレンダーが作成されます(*ngForなので当たり前ですが)
Firebaseにイベントが3つあるとして、idが a, b, c とします。
するとカレンダーが3つ作成され、一番上のカレンダーのどこを押してもidがaとなり、真ん中のカレンダーのどこを押してもidがbとなり、、、
という感じです。
カレンダーが1つで、かつ日付ごとにイベントを判別できない状態です。
仮に5日にイベントがあったとして、5日を押すと5日のページに遷移し、イベントありと表記されている。6日を押すと6日のページに遷移するが、イベントなしと表記されている。
このような状態にしたいです。
該当のソースコード
home.page.html
html
1<ion-header> 2 <ion-toolbar color="danger"> 3 <ion-buttons slot="start"> 4 <ion-menu-button></ion-menu-button> 5 </ion-buttons> 6 <ion-title> 7 {{ viewTitle }} 8 </ion-title> 9 <ion-buttons slot="end"> 10 <ion-button (click)="today()">Today</ion-button> 11 </ion-buttons> 12 </ion-toolbar> 13</ion-header> 14 15<ion-content padding> 16 17 <calendar [eventSource]="eventSource" 18 [calendarMode]="calendar.mode" 19 [currentDate]="calendar.currentDate" 20 (onCurrentDateChanged)="onCurrentDateChanged($event)" 21 (onEventSelected)="onEventSelected($event)" 22 (onTitleChanged)="onViewTitleChanged($event)" 23 (onTimeSelected)="onTimeSelected($event)" 24 [locale]="calendar.locale" 25 [routerLink]="['/day', dayEvent.id]" 26 > 27</calendar> 28 29<ion-list> 30 <ion-item *ngFor="let dayEvent of (dayEvents | async)"> 31 <!-- イベントのidは取れている --> 32 <p>{{ dayEvent.id }}</p> 33 </ion-item> 34</ion-list> 35</ion-content>
home.service.ts
typescript
1import { Injectable } from '@angular/core'; 2import { Observable } from 'rxjs'; 3import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/firestore'; 4import { map, take } from 'rxjs/operators'; 5 6export interface DayEvent { 7 id?: string; 8 title: string; 9 endTime: Date; 10 startTime: Date; 11 allDay: boolean; 12} 13 14@Injectable({ 15 providedIn: 'root' 16}) 17export class HomeService { 18 // 取得したコレクションを格納 19 private dayCollection: AngularFirestoreCollection<DayEvent>; 20 // コレクションのストリームを格納 21 private dayEvents: Observable<DayEvent[]>; 22 23 eventSource = []; 24 selectedDate = new Date(); 25 26 constructor( 27 private afs: AngularFirestore 28 ) 29 { 30 // コレクションを取得してdayCollectionに格納 31 this.dayCollection = this.afs.collection<DayEvent>(`events`); 32 this.dayEvents = this.dayCollection.snapshotChanges().pipe( 33 map(actions => { 34 return actions.map(a => { 35 const event = a.payload.doc.data(); 36 const id = a.payload.doc.id; 37 return { id, ...event }; 38 }); 39 }) 40 ); 41 } 42 43 getEvents(): Observable<DayEvent[]> { 44 return this.dayEvents; 45} 46 47 getEvent(id: string) { 48 return this.dayCollection.doc<DayEvent>(id).valueChanges().pipe( 49 take(1), 50 map(dayEvent => { 51 dayEvent.id = id; 52 console.log('getEventで取った ' + dayEvent.id); 53 return dayEvent; 54 }) 55 ); 56 } 57 58 addNewEvent() { 59 const start = this.selectedDate; 60 const end = this.selectedDate; 61 end.setMinutes(end.getHours() + 1); 62 const event = { 63 title: 'Event #' + start.getMinutes(), 64 startTime: start, 65 endTime: end, 66 allDay: true 67 }; 68 console.log('イベント登録' + start); 69 // this.db.collection(`users/${this.authService.userId}/events`); 70 return this.afs.collection(`events`).add(event); 71 } 72 73 deleteEvent(id: string): Promise<void> { 74 return this.afs.collection(`events`).doc(id).delete(); 75 } 76 77}
home.page.ts
typescript
1import { AngularFirestore } from '@angular/fire/firestore'; 2import { HomeService, DayEvent } from './home.service'; 3import { Component, OnInit } from '@angular/core'; 4import { Router } from '@angular/router'; 5import { Observable } from 'rxjs'; 6 7@Component({ 8 selector: 'app-home', 9 templateUrl: 'home.page.html', 10 styleUrls: ['home.page.scss'], 11}) 12export class HomePage implements OnInit { 13 eventSource = []; 14 viewTitle; 15 calendar = { 16 mode: 'month', 17 currentDate: new Date(), 18 locale: 'ja-JP' 19 }; 20 21 // ここでのプロパティがhtmlで使われる 22 private dayEvents: Observable<DayEvent[]>; 23 24 25 constructor( 26 private router: Router, 27 private homeService: HomeService, 28 private db: AngularFirestore 29 ) { 30 // Firebaseからイベント取得 31 this.db.collection(`events`).snapshotChanges().subscribe(colSnap => { 32 this.eventSource = []; 33 colSnap.forEach(snap => { 34 const event: any = snap.payload.doc.data(); 35 event.id = snap.payload.doc.id; 36 event.startTime = event.startTime.toDate(); 37 event.endTime = event.endTime.toDate(); 38 this.eventSource.push(event); 39 }); 40 }); 41 42 } 43 44 45 ngOnInit() { 46 this.dayEvents = this.homeService.getEvents(); 47 } 48 49 onViewTitleChanged(title) { 50 this.viewTitle = title; 51 } 52 53 54 55 onEventSelected(event) { 56 console.log('Event selected:' + event.startTime + '-' + event.endTime + ',' + event.title); 57 } 58 59 // 選択した日付を取得&サービスのaddNewEventを設定 60 onTimeSelected(ev) { 61 const selected = new Date(ev.selectedTime); 62 console.log('選択した日は ' + selected); 63 this.homeService.selectedDate = selected; 64 } 65 66 onCurrentDateChanged(event: Date) { 67 } 68 69 reloadSource(ev) { 70 console.log('range changed: startTime: ' + ev.startTime + ', endTime: ' + ev.endTime); 71 } 72 73 74 today() { 75 this.calendar.currentDate = new Date(); 76 } 77}
day.page.html
html
1<ion-header> 2 <ion-toolbar> 3 <ion-buttons slot="start"> 4 <ion-back-button defaultHref="/home"></ion-back-button> 5 </ion-buttons> 6 <ion-buttons slot="end"> 7 <ion-button (click)="addNewEvent()">登録</ion-button> 8 </ion-buttons> 9 <ion-title> 10 Dayページ 11 </ion-title> 12 </ion-toolbar> 13</ion-header> 14 15<ion-content> 16 <ion-button (click)="deleteEvent()">削除</ion-button> 17 <!-- ここのidのイベントが削除される --> 18 <p>{{ dayEvent.id }}</p> 19</ion-content>
day.page.ts
typescript
1import { HomeService, DayEvent } from './../home/home.service'; 2import { Component, OnInit } from '@angular/core'; 3import { Router, ActivatedRoute } from '@angular/router'; 4import { ToastController } from '@ionic/angular'; 5 6 7@Component({ 8 selector: 'app-day', 9 templateUrl: './day.page.html', 10 styleUrls: ['./day.page.scss'], 11}) 12 13export class DayPage implements OnInit { 14 eventSource = []; 15 viewTitle; 16 selectedDate = new Date(); 17 18 dayEvent: DayEvent = { 19 title: '', 20 startTime: this.selectedDate, 21 endTime: this.selectedDate, 22 allDay: true 23 }; 24 id = null; 25 26 constructor( 27 private homeService: HomeService, 28 private router: Router, 29 private activatedRoute: ActivatedRoute, 30 private toastCtrl: ToastController, 31 ) { 32 } 33 34 ngOnInit() { 35 // idを取得 36 this.id = this.activatedRoute.snapshot.paramMap.get('id'); 37 } 38 39 ionViewWillEnter() { 40 if (this.id) { 41 this.homeService.getEvent(this.id).subscribe(dayEvent => { 42 this.dayEvent = dayEvent; 43 }); 44 } 45 } 46 47 48 addNewEvent() { 49 this.homeService.addNewEvent().then(() => { 50 this.router.navigateByUrl('/'); 51 }); 52 } 53 54 deleteEvent() { 55 this.homeService.deleteEvent(this.dayEvent.id).then(() => { 56 this.router.navigateByUrl('/'); 57 this.showToast('削除しました'); 58 }, 59 err => { 60 this.showToast('問題が発生しました。削除できなかったです。'); 61 }); 62 } 63 64 showToast(msg) { 65 this.toastCtrl.create({ 66 message: msg, 67 duration: 2000 68 }).then(toast => toast.present()); 69 } 70}
回答1件
あなたの回答
tips
プレビュー