#現象
こちらの動画を参考に!
#環境と概要
yaml
1environment: 2 sdk: ">=2.7.0 <3.0.0" 3 4dependencies: 5 flutter: 6 sdk: flutter 7 provider: ^4.3.3
Firebaseを使っていますが、あまり関係がなさそうなのでこの投稿内容では割愛します!
アプリの内容は、好きな映画をコメントと一緒に保存できる、という物です。
今回問題になっているのは「コメントの追加、編集、削除」です。
ToDoリストのようなものを想像していただけると良いかと。。
#ソースの構造
console
1lib/ 2 ├ main.dart 3 ├ models 4 ├ └ mypage_movie_model.dart // データ構造 5 ├ providers 6 │ └ mypage_movie_provider.dart // prodiverの処理 7 ├ widgets 8 ├ save_movie_text.dart // 保存ボタン 9 └ mypage_movie_form.dart // Formの部分
#現象の詳細
##実現したいこと
①mypage_movie_form.dart
で値を入力
↓
②mypage_movie_provider.dart
で定義しているpoint1Text
に、①で入力された内容が入る
↓
③save_movie_text.dart
の保存ボタンを押したときに、point1Text
が保存される
##現状の問題
①mypage_movie_form.dart
で値を入力
↓
②mypage_movie_provider.dart
で定義しているpoint1Text
に、①で入力された内容が入る
↓
③save_movie_text.dart
の保存ボタンを押したときに、point1Text
が空っぽになっている
#該当のソース
##main.dart
dart:main.dart
1class Home extends StatelessWidget { 2 3 Widget build(BuildContext context) { 4 return MultiProvider( 5 providers: [ 6 ChangeNotifierProvider( 7 create: (context) => MyPageMovieProvider(), 8 ), 9 ], 10 child: MaterialApp( 11 // 省略
##mypage_movie_model.dart
dart:mypage_movie_model.dart
1import 'package:cloud_firestore/cloud_firestore.dart'; 2 3class MyPageMovieModel { 4 MyPageMovieModel(DocumentSnapshot doc) { 5 movieId = doc.id; 6 title = doc.data()['title']; 7 pointText1 = doc.data()['point1']; 8 } 9 String movieId; 10 String title; 11 String pointText1; 12}
##mypage_movie_provider.dart
dart:mypage_movie_provider.dart
1import '../models/mypage_movie_model.dart'; 2 3class MyPageMovieProvider with ChangeNotifier { 4 MyPageMovieModel myPageMovie; 5 String point1Text = ''; 6 final uid = FirebaseAuth.instance.currentUser.uid; 7 final FirebaseFirestore _firestore = FirebaseFirestore.instance; 8 9 Future fetchMyMovies(int movieId) async { 10 final docs = 11 await _firestore.doc('users/${uid}/movies/${movieId.toString()}').get(); 12 this.myPageMovie = MyPageMovieModel(docs); 13 notifyListeners(); 14 } 15 16 Future editMyMovies(int movieId, String title) async { 17 final movieRef = 18 _firestore.doc('users/${uid}/movies/${movieId.toString()}'); 19 await movieRef.update({ 20 'id': movieId, 21 'title': title, 22 'point1': point1Text, // point1Textが空っぽなので何も保存されない 23 }); 24 } 25}
##save_movie_text.dart
dart:save_movie_text.dart
1import 'mypage_movie_form.dart'; 2import '../../providers/mypage_movie_provider.dart'; 3 4class SaveMovieText extends StatelessWidget { 5 final int id; 6 final String title; 7 SaveMovieText(this.id, this.title); 8 9 10 Widget build(BuildContext context) { 11 return Consumer<MyPageMovieProvider>(builder: (context, model, child) { 12 return FloatingActionButton( 13 onPressed: () async { 14 print('保存' + id.toString()); 15 await model.editMyMovies(id, title); 16 print(model.point1Text); // 空っぽ 17 }, 18 ); 19 }); 20 } 21}
##mypage_movie_form.dart
dart:mypage_movie_form.dart
1import '../../providers/mypage_movie_provider.dart'; 2 3class MyPageMovieForm extends StatelessWidget { 4 final int id; 5 MyPageMovieForm(this.id); 6 7 final formKey = GlobalKey<FormState>(); 8 9 10 Widget build(BuildContext context) { 11 return ChangeNotifierProvider<MyPageMovieProvider>.value( 12 value: MyPageMovieProvider()..fetchMyMovies(id), 13 child: Consumer<MyPageMovieProvider>( 14 builder: (context, model, child) { 15 final movie = model.myPageMovie; 16 return movie == null 17 ? Center(child: CircularProgressIndicator()) 18 : Form( 19 key: formKey, 20 child: ListView( 21 // 省略 22 Expanded( 23 child: TextFormField( 24 controller: TextEditingController( 25 text: 26 movie.pointText1 != null ? movie.pointText1 : '', 27 ), 28 decoration: InputDecoration(labelText: '見所1'), 29 onChanged: (value) { 30 model.point1Text = value; 31 print(model.point1Text); // ここでは値が入ってる!!! 32 }, 33 ), 34 ), 35 ], 36 ), 37 ], 38 ), 39 ); 40 }, 41 ), 42 ); 43 } 44}
#想定される原因
##ChangeNotifierProviderが原因?
もしmypage_movie_form.dart
でChangeNotifierProvider
を使わなかった場合、save_movie_text.dart
のmodel.point1Text
にしっかり値が入っています。
dart:mypage_movie_form.dart
1 2 Widget build(BuildContext context) { 3 return Consumer<MyPageMovieProvider>(builder: (context, model, child) { 4 return Form( 5 key: formKey, 6 // 省略 7 onChanged: (value) { 8 model.point1Text = value; 9 print(model.point1Text); 10 },
dart:save_movie_text.dart
1class SaveMovieText extends StatelessWidget { 2 final int id; 3 final String title; 4 SaveMovieText(this.id, this.title); 5 6 7 Widget build(BuildContext context) { 8 return Consumer<MyPageMovieProvider>(builder: (context, model, child) { 9 return FloatingActionButton( 10 onPressed: () async { 11 await model.editMyMovies(id, title); 12 print(model.point1Text); // 値が入ってる
なぜmypage_movie_form.dart
でChangeNotifierProvider
を使っているかというと、もしコメントが保存されていたら、その内容を入力欄にデフォルトで表示したいからです。
そしてコメントを取得するにはmovie id
が必要なので、mypage_movie_form.dart
でChangeNotifierProvider
を使っています。
他にいい方法があれば教えてください!!!
#試したこと
mypage_movie_provider.dart
で定義されているpoint1Text
に初期値を入れてみました。
dart:mypage_movie_provider.dart
1import '../models/mypage_movie_model.dart'; 2 3class MyPageMovieProvider with ChangeNotifier { 4 MyPageMovieModel myPageMovie; 5 String point1Text = 'テストです'; // ここに値を入れてみる 6 final uid = FirebaseAuth.instance.currentUser.uid; 7 final FirebaseFirestore _firestore = FirebaseFirestore.instance; 8 9}
しかし、保存ボタンを押したときmodel.point1Text
は空っぽでした!!!
dart:save_movie_text.dart
1class SaveMovieText extends StatelessWidget { 2 3 4 Widget build(BuildContext context) { 5 return Consumer<MyPageMovieProvider>(builder: (context, model, child) { 6 return FloatingActionButton( 7 onPressed: () async { 8 await model.editMyMovies(id, title); 9 print(model.point1Text); // 「テストです」が表示されず空っぽ 10 }, 11 ); 12 }); 13 } 14}
#最後に
Providerが難しくてあまり理解できていません。。どなたかご教授いただけると幸いです!
関連記事
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。