Flutter:在流中访问 SharedPreferences Provider / ChangeNotifier Class
Flutter: Access SharedPreferences Provider / ChangeNotifier in a Stream Class
我在 Whosebug 中四处寻找,但没能找到解决方案。
设想:
我有一个带有 ChangeNotifier Class 的 Flutter SharedPreferences Provider,它将使用当前登录的用户信息进行更新。
简化内容:
class SharedPreferences {
final String userId;
final String userName;
SharedPreferences({
@required this.userId,
@required this.userName,
});
}
class SharedPreferencesData with ChangeNotifier {
var _sharedPreferencesData = SharedPreferences(
userId: 'testUserId',
userName: 'testUserName',
);}
还有一个 database.dart 文件 Class 包含用于从快照获取 FireStore 流的 DataBaseServices:
class DatabaseService {
final CollectionReference companiesProfilesCollection =
Firestore.instance.collection('companiesProfiles');
List<CompanyProfile> _companiesProfilesFromSnapshot(QuerySnapshot snapshot) {
return snapshot.documents.map((doc) {
return CompanyProfile(
docId: doc.documentID,
companyName: doc.data['companyName'] ?? '',
maxLocationsNumber: doc.data['maxLocationsNumber'] ?? 0,
maxUsersNumber: doc.data['maxUsersNumber'] ?? 0,
);
}).toList();
}
Stream<List<CompanyProfile>> get getCompaniesProfiles {
return companiesProfilesCollection
.where('userId', isEqualTo: _userIdFromProvider)
// My problem is above -----
.snapshots()
.map(_companiesProfilesFromSnapshot);
}
}
我不想获取整个 Stream 数据,因为它对于其他 Stream 来说可能很大,我只想在 .where('userId', isEqualTo:_userIdFromProvider) 下传递 userID。
我无法访问此 class 中的上下文以从提供程序
获取数据
无法将用户 ID 发送到 getCompaniesProfiles getter,因为 getter 不接受参数
如果我将此 getter 转换为常规方法,我将无法将用户 ID 发送给它,因为这必须 运行 在 void main() {运行App(MyApp());} / return MultiProvider(providers: [ 到那时,我无法使用不包含上下文的上下文调用获取 sharedPreferences包含提供商信息 ...
无法弄清楚如何在此 class 中将上下文作为构造函数接收,当我这样做时,我得到以下内容 Only static members can accessed in class 数据库服务中的初始值设定项。
我还是个初学者,如果您能与我分享处理此问题的最佳方法,我将不胜感激。
谢谢!
*********** 通过添加以下内容重新编辑:**************
我正在尝试实现相同的场景,这是我的代码:
主文件:
return MultiProvider(
providers: [
ChangeNotifierProvider<SpData>(
create: (context) => SpData(),
),
ProxyProvider<SpData, DS>(
create: (context) => DS(),
update: (ctx, spData, previousDS) {
print('ChangeNotifierProxyProvider RAN');
previousDS.dbData = spData;
return previousDS;
},
),
],
SP 文件:
class SP {
final String companyId;
SP({
@required this.companyId,
});
}
class SpData with ChangeNotifier {
var _sPData = SP(
companyId: '',
);
void setCompanyId(String cpID) {
final newSharedPreferences = SP(
companyId: cpID,
);
_sPData = newSharedPreferences;
print('_spData companyId:${_sPData.companyId}');
notifyListeners();
}
String get getCompanyId {
return _sPData.companyId;
}
}
DS 文件:
class DS with ChangeNotifier {
SpData dbData;
void printCompanyId() {
var companyId = dbData.getCompanyId;
print('companyId from DataBase: $companyId');
}
}
SpData dbData; inside Class DS 不更新。我已经添加了指纹来弄清楚什么是 运行ning 什么不是。当我 运行 我的代码时, main.dart 文件中的打印函数 print('ChangeNotifierProxyProvider RAN');没有 运行.
我错过了什么?为什么没有触发 ChangeNotifierProxyProvider 来更新 DS 文件中的 dbData?谢谢!
您可以使用 ProxyProvider
来达到这个目的。
ProxyProvider
是一个基于其他提供者构建价值的提供者。
你说你有一个 MultiProvider
,所以我猜你在这个 MultiProvider
中有 SharedPreferencesData
个提供者,然后是 DatabaseService
个提供者。您需要做的是将 ProxyProvider
用于 DatabaseService
而不是常规提供程序,并将其基于 SharedPreferencesData
提供程序。
这是一个例子:
MultiProvider(
providers: [
ChangeNotifierProvider<SharedPreferencesData>(
create: (context) => SharedPreferencesData(),
),
ProxyProvider<SharedPreferencesData, DatabaseService>(
create: (context) => DatabaseService(),
update: (context, sharedPreferencesData, databaseService) {
databaseService.sharedPreferencesData = sharedPreferencesData;
return databaseService;
},
dispose: (context, databaseService) => databaseService.dispose(),
),
],
child: ...
上面的代码片段是这样的:
ProxyProvider
每次 SharedPreferencesData
变化时调用 update
。
DatabaseService
在 update
. 中设置其 sharedPreferencesData
变量
现在您可以访问 DatabaseService
实例中的 sharedPreferencesData
,您可以轻松地做您想做的事了。
我在 Whosebug 中四处寻找,但没能找到解决方案。 设想: 我有一个带有 ChangeNotifier Class 的 Flutter SharedPreferences Provider,它将使用当前登录的用户信息进行更新。
简化内容:
class SharedPreferences {
final String userId;
final String userName;
SharedPreferences({
@required this.userId,
@required this.userName,
});
}
class SharedPreferencesData with ChangeNotifier {
var _sharedPreferencesData = SharedPreferences(
userId: 'testUserId',
userName: 'testUserName',
);}
还有一个 database.dart 文件 Class 包含用于从快照获取 FireStore 流的 DataBaseServices:
class DatabaseService {
final CollectionReference companiesProfilesCollection =
Firestore.instance.collection('companiesProfiles');
List<CompanyProfile> _companiesProfilesFromSnapshot(QuerySnapshot snapshot) {
return snapshot.documents.map((doc) {
return CompanyProfile(
docId: doc.documentID,
companyName: doc.data['companyName'] ?? '',
maxLocationsNumber: doc.data['maxLocationsNumber'] ?? 0,
maxUsersNumber: doc.data['maxUsersNumber'] ?? 0,
);
}).toList();
}
Stream<List<CompanyProfile>> get getCompaniesProfiles {
return companiesProfilesCollection
.where('userId', isEqualTo: _userIdFromProvider)
// My problem is above -----
.snapshots()
.map(_companiesProfilesFromSnapshot);
}
}
我不想获取整个 Stream 数据,因为它对于其他 Stream 来说可能很大,我只想在 .where('userId', isEqualTo:_userIdFromProvider) 下传递 userID。
我无法访问此 class 中的上下文以从提供程序
获取数据无法将用户 ID 发送到 getCompaniesProfiles getter,因为 getter 不接受参数
如果我将此 getter 转换为常规方法,我将无法将用户 ID 发送给它,因为这必须 运行 在 void main() {运行App(MyApp());} / return MultiProvider(providers: [ 到那时,我无法使用不包含上下文的上下文调用获取 sharedPreferences包含提供商信息 ...
无法弄清楚如何在此 class 中将上下文作为构造函数接收,当我这样做时,我得到以下内容 Only static members can accessed in class 数据库服务中的初始值设定项。
我还是个初学者,如果您能与我分享处理此问题的最佳方法,我将不胜感激。 谢谢!
*********** 通过添加以下内容重新编辑:************** 我正在尝试实现相同的场景,这是我的代码: 主文件:
return MultiProvider(
providers: [
ChangeNotifierProvider<SpData>(
create: (context) => SpData(),
),
ProxyProvider<SpData, DS>(
create: (context) => DS(),
update: (ctx, spData, previousDS) {
print('ChangeNotifierProxyProvider RAN');
previousDS.dbData = spData;
return previousDS;
},
),
],
SP 文件:
class SP {
final String companyId;
SP({
@required this.companyId,
});
}
class SpData with ChangeNotifier {
var _sPData = SP(
companyId: '',
);
void setCompanyId(String cpID) {
final newSharedPreferences = SP(
companyId: cpID,
);
_sPData = newSharedPreferences;
print('_spData companyId:${_sPData.companyId}');
notifyListeners();
}
String get getCompanyId {
return _sPData.companyId;
}
}
DS 文件:
class DS with ChangeNotifier {
SpData dbData;
void printCompanyId() {
var companyId = dbData.getCompanyId;
print('companyId from DataBase: $companyId');
}
}
SpData dbData; inside Class DS 不更新。我已经添加了指纹来弄清楚什么是 运行ning 什么不是。当我 运行 我的代码时, main.dart 文件中的打印函数 print('ChangeNotifierProxyProvider RAN');没有 运行.
我错过了什么?为什么没有触发 ChangeNotifierProxyProvider 来更新 DS 文件中的 dbData?谢谢!
您可以使用 ProxyProvider
来达到这个目的。
ProxyProvider
是一个基于其他提供者构建价值的提供者。
你说你有一个 MultiProvider
,所以我猜你在这个 MultiProvider
中有 SharedPreferencesData
个提供者,然后是 DatabaseService
个提供者。您需要做的是将 ProxyProvider
用于 DatabaseService
而不是常规提供程序,并将其基于 SharedPreferencesData
提供程序。
这是一个例子:
MultiProvider(
providers: [
ChangeNotifierProvider<SharedPreferencesData>(
create: (context) => SharedPreferencesData(),
),
ProxyProvider<SharedPreferencesData, DatabaseService>(
create: (context) => DatabaseService(),
update: (context, sharedPreferencesData, databaseService) {
databaseService.sharedPreferencesData = sharedPreferencesData;
return databaseService;
},
dispose: (context, databaseService) => databaseService.dispose(),
),
],
child: ...
上面的代码片段是这样的:
ProxyProvider
每次SharedPreferencesData
变化时调用update
。DatabaseService
在update
. 中设置其
sharedPreferencesData
变量
现在您可以访问 DatabaseService
实例中的 sharedPreferencesData
,您可以轻松地做您想做的事了。