ChangeNotifierProxyProvider 颤振未从 ChangeNotifierProvider 获取更新
ChangeNotifierProxyProvider flutter not getting update from ChangeNotifierProvider
我正在尝试从 ItemProvider
中的 UserProvider
访问 userModel.uid
以便它可以加载 _savedItems
.
但是,当我调用 loadUserSavedItems()
时,_userId
为空。
这是我的 main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'providers/user.dart';
import 'providers/item.dart';
import 'screens/home.dart';
void main() {
Provider.debugCheckInvalidValueType = null;
WidgetsFlutterBinding.ensureInitialized();
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<UserProvider>(
create: (_) => UserProvider.initialize()),
ChangeNotifierProxyProvider<UserProvider, ItemProvider>(
create: (_) => ItemProvider(),
update: (_, userProvider, itemProvider) => itemProvider,
),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.white,
primaryTextTheme: TextTheme(
headline6: TextStyle(color: Colors.black),
),
),
home: Home(),
),
),
);
}
UserProvider.dart
import 'models/user.dart';
import 'services/user.dart';
enum Status { Uninitialized, Authenticated, Authenticating, Unauthenticated }
class UserProvider extends ChangeNotifier {
FirebaseAuth _auth;
FirebaseUser _user;
Status _status = Status.Uninitialized;
Firestore _firestore = Firestore.instance;
UserServices _userServicse = UserServices();
UserModel _userModel;
// getter
UserModel get userModel => _userModel;
Status get status => _status;
FirebaseUser get user => _user;
UserProvider.initialize() : _auth = FirebaseAuth.instance {
_auth.onAuthStateChanged.listen(_onStateChanged);
notifyListeners();
}
Future<void> _onStateChanged(FirebaseUser firebaseUser) async {
if (firebaseUser == null) {
_status = Status.Unauthenticated;
} else {
_user = firebaseUser;
_status = Status.Authenticated;
_userModel = await _userServicse.getUserById(user.uid);
}
notifyListeners();
}
Future<bool> signIn() async {
bool retVal = false;
try {
_status = Status.Authenticating;
notifyListeners();
AuthResult _authResult = await _auth.signInWithEmailAndPassword(
email: email.text.trim(), password: password.text.trim());
if (_authResult.user != null) {
retVal = true;
}
} catch (e) {
_status = Status.Unauthenticated;
notifyListeners();
print(e.toString());
}
return retVal;
}
}
ItemProvider.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/foundation.dart';
import 'models/item.dart';
import 'providers/user.dart';
import 'services/item.dart';
class ItemProvider extends ChangeNotifier {
ItemProvider({UserProvider userProvider}) : _userProvider = userProvider;
UserProvider _userProvider;
final databaseReference = Firestore.instance;
ItemServices _itemServices = ItemServices();
List<Item> _items = [];
List<Item> _savedItems = [];
String _userId;
// getter
List<Item> get items => _items;
List<Item> get savedItems => _savedItems;
String get userId => _userId;
UserProvider get userProvider => _userProvider;
//get the items to load when the app is initiated
ItemProvider.initialize() {
loadAllActiveItems();
if (_userProvider.status == Status.Authenticated) {
loadUserSavedItems();
}
}
//get active items from DB
loadAllActiveItems() async {
_items = await _itemServices.getBatchOfActiveItems();
notifyListeners();
}
//get user saved items from DB
loadUserSavedItems() async {
_userId = userProvider.userModel.uid;
_savedItems = await _itemServices.getUserSavedItems(userId);
notifyListeners();
}
}
有人可以帮助我吗,我不太确定我错过了什么,不能 userModel
object/properties 在 ItemProvider.dart
中实现为 ChangeNotifierProxyProvider
。
我终于找到了解决方法,虽然不是最好的,但确实有效。
在 ItemProvider
内部创建了 updates()
以接收来自
的 userId
void updates(String userId, Status status) {
this._userId = userId;
}
然后在 main.dart
中进行更改以从 ChangeNotifierProxyProvider
传递 userId
。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'providers/user.dart';
import 'providers/item.dart';
import 'screens/home.dart';
void main() {
Provider.debugCheckInvalidValueType = null;
WidgetsFlutterBinding.ensureInitialized();
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<UserProvider>(
create: (_) => UserProvider.initialize()),
ChangeNotifierProxyProvider<UserProvider, ItemProvider>(
create: (_) => ItemProvider(),
update: (_, userProvider, itemProvider) => itemProvider
..updates(
userProvider.user != null ? userProvider.user.uid : ''),
),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.white,
primaryTextTheme: TextTheme(
headline6: TextStyle(color: Colors.black),
),
),
home: Home(),
),
),
);
}
很高兴听到其他人也做了什么。
我正在尝试从 ItemProvider
中的 UserProvider
访问 userModel.uid
以便它可以加载 _savedItems
.
但是,当我调用 loadUserSavedItems()
时,_userId
为空。
这是我的 main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'providers/user.dart';
import 'providers/item.dart';
import 'screens/home.dart';
void main() {
Provider.debugCheckInvalidValueType = null;
WidgetsFlutterBinding.ensureInitialized();
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<UserProvider>(
create: (_) => UserProvider.initialize()),
ChangeNotifierProxyProvider<UserProvider, ItemProvider>(
create: (_) => ItemProvider(),
update: (_, userProvider, itemProvider) => itemProvider,
),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.white,
primaryTextTheme: TextTheme(
headline6: TextStyle(color: Colors.black),
),
),
home: Home(),
),
),
);
}
UserProvider.dart
import 'models/user.dart';
import 'services/user.dart';
enum Status { Uninitialized, Authenticated, Authenticating, Unauthenticated }
class UserProvider extends ChangeNotifier {
FirebaseAuth _auth;
FirebaseUser _user;
Status _status = Status.Uninitialized;
Firestore _firestore = Firestore.instance;
UserServices _userServicse = UserServices();
UserModel _userModel;
// getter
UserModel get userModel => _userModel;
Status get status => _status;
FirebaseUser get user => _user;
UserProvider.initialize() : _auth = FirebaseAuth.instance {
_auth.onAuthStateChanged.listen(_onStateChanged);
notifyListeners();
}
Future<void> _onStateChanged(FirebaseUser firebaseUser) async {
if (firebaseUser == null) {
_status = Status.Unauthenticated;
} else {
_user = firebaseUser;
_status = Status.Authenticated;
_userModel = await _userServicse.getUserById(user.uid);
}
notifyListeners();
}
Future<bool> signIn() async {
bool retVal = false;
try {
_status = Status.Authenticating;
notifyListeners();
AuthResult _authResult = await _auth.signInWithEmailAndPassword(
email: email.text.trim(), password: password.text.trim());
if (_authResult.user != null) {
retVal = true;
}
} catch (e) {
_status = Status.Unauthenticated;
notifyListeners();
print(e.toString());
}
return retVal;
}
}
ItemProvider.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/foundation.dart';
import 'models/item.dart';
import 'providers/user.dart';
import 'services/item.dart';
class ItemProvider extends ChangeNotifier {
ItemProvider({UserProvider userProvider}) : _userProvider = userProvider;
UserProvider _userProvider;
final databaseReference = Firestore.instance;
ItemServices _itemServices = ItemServices();
List<Item> _items = [];
List<Item> _savedItems = [];
String _userId;
// getter
List<Item> get items => _items;
List<Item> get savedItems => _savedItems;
String get userId => _userId;
UserProvider get userProvider => _userProvider;
//get the items to load when the app is initiated
ItemProvider.initialize() {
loadAllActiveItems();
if (_userProvider.status == Status.Authenticated) {
loadUserSavedItems();
}
}
//get active items from DB
loadAllActiveItems() async {
_items = await _itemServices.getBatchOfActiveItems();
notifyListeners();
}
//get user saved items from DB
loadUserSavedItems() async {
_userId = userProvider.userModel.uid;
_savedItems = await _itemServices.getUserSavedItems(userId);
notifyListeners();
}
}
有人可以帮助我吗,我不太确定我错过了什么,不能 userModel
object/properties 在 ItemProvider.dart
中实现为 ChangeNotifierProxyProvider
。
我终于找到了解决方法,虽然不是最好的,但确实有效。
在 ItemProvider
内部创建了 updates()
以接收来自
userId
void updates(String userId, Status status) {
this._userId = userId;
}
然后在 main.dart
中进行更改以从 ChangeNotifierProxyProvider
传递 userId
。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'providers/user.dart';
import 'providers/item.dart';
import 'screens/home.dart';
void main() {
Provider.debugCheckInvalidValueType = null;
WidgetsFlutterBinding.ensureInitialized();
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<UserProvider>(
create: (_) => UserProvider.initialize()),
ChangeNotifierProxyProvider<UserProvider, ItemProvider>(
create: (_) => ItemProvider(),
update: (_, userProvider, itemProvider) => itemProvider
..updates(
userProvider.user != null ? userProvider.user.uid : ''),
),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.white,
primaryTextTheme: TextTheme(
headline6: TextStyle(color: Colors.black),
),
),
home: Home(),
),
),
);
}
很高兴听到其他人也做了什么。