所以我有这个结构
他们两个都使用相同的Bloc NotificationBLoc()
class NotificationBLoc extends Bloc<NotificationEvent, NotificationState> {
@override
NotificationState get initialState => InitialNotification();
@override
Stream<NotificationState> mapEventToState(NotificationEvent event) async* {
final currentState = state;
if (event is FetchNotification && !_hasReachedMax(currentState)) {
try {
if (currentState is InitialNotification) {
yield LoadNotification();
final posts = await fetchNotification(0, 10, event.userId);
yield NotificationLoaded(notif: posts, hasReachedMax: false);
return;
}
if (currentState is NotificationLoaded) {
final posts = await fetchNotification(
currentState.notif.length, 10, event.userId);
yield posts.isEmpty
? currentState.copyWith(hasReachedMax: true)
: NotificationLoaded(
notif: currentState.notif + posts,
hasReachedMax: false,
);
}
} catch (e) {
print(e.toString());
yield NotificationError();
}
}
if (event is OpenNotification) {
if (currentState is NotificationLoaded) {
currentState.notif[event.notificationIndex].notificationFlag = "1";
List<Notif> filteredRecored = new List<Notif>();
currentState.notif.forEach((r) {
filteredRecored.add(r);
});
yield NotificationLoaded(notif: filteredRecored, hasReachedMax: false);
}
}
}
bool _hasReachedMax(NotificationState state) =>
state is NotificationLoaded && state.hasReachedMax;
Future<List<Notif>> fetchNotification(
int limit, int offset, String userId) async {
final response = await http.Client().post(
Configuration.url +
"api/getNotification/" +
limit.toString() +
"/" +
offset.toString() +
"/",
body: {"userId": userId});
if (response.statusCode < 200 || response.statusCode > 300) {
throw new Exception('Failed to fetch data');
} else {
List<dynamic> responseData = jsonDecode(response.body);
final List<Notif> notif = [];
responseData.forEach((singleChild) {
notif.add(
Notif(
notificationId: singleChild['notificationId'],
notificationTitle: singleChild['notificationTitle'],
notificationBody: singleChild['notificationBody'],
notificationDate: singleChild['notificationDate'],
notificationTo: singleChild['notificationTo'],
notificationImage: singleChild['notificationImage'],
notificationFlag: singleChild['notificationFlag'],
),
);
});
return notif;
}
}
}
在第一个结构中(在CustomAppBar内部),我这样做
notificationBLoc.add(FetchNotification(userId: userId));
这是CustomAppBar内部使用Bloc的
BlocBuilder<NotificationBLoc, NotificationState>(
builder: (context, state) {
if (state is NotificationLoaded) {
List<Notif> filteredRecored = new List<Notif>();
state.notif.forEach((f) {
if (f.notificationFlag.toLowerCase().contains("0") ||
f.notificationFlag.contains("0")) {
filteredRecored.add(f);
}
});
print(filteredRecored.length.toString());
return new Stack(
children: <Widget>[
new IconButton(
icon: Icon(
Icons.notifications,
color: Colors.brown,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NotificationPage()),
);
},
),
filteredRecored.length != 0
? new Positioned(
right: 7,
top: 5,
child: new Container(
decoration: new BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(6),
),
constraints: BoxConstraints(
minWidth: 15,
minHeight: 15,
),
child: Text(
filteredRecored.length.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 11,
),
textAlign: TextAlign.center,
),
),
)
: new Container(),
],
);
} else {
return Container(
child: null,
);
}
},
),
它显示6(总计数据)。
然后我执行此操作以在第二个结构中获取数据
notificationBLoc = BlocProvider.of<NotificationBLoc>(context);
notificationBLoc.add(FetchNotification(userId: userId));
数据显示的与我期望的一样,然后从列表中单击一个。那个刺激
notificationBLoc.add(OpenNotification(notificationIndex: index));
因此它将运行
if (event is OpenNotification) {
if (currentState is NotificationLoaded) {
currentState.notif[event.notificationIndex].notificationFlag = "1";
List<Notif> filteredRecored = new List<Notif>();
currentState.notif.forEach((r) {
filteredRecored.add(r);
});
yield NotificationLoaded(notif: filteredRecored, hasReachedMax: false);
}
}
因此,在第一个结构中,数据长度仍然是6,而不是5。当我重新打开应用程序时,数据长度变成5。
我想念什么吗?
这是我的Bloc状态
abstract class NotificationState extends Equatable {
const NotificationState();
@override
List<Object> get props => [];
}
class InitialNotification extends NotificationState {}
class LoadNotification extends NotificationState {}
class NotificationLoaded extends NotificationState {
final List<Notif> notif;
final bool hasReachedMax;
const NotificationLoaded({
this.notif,
this.hasReachedMax,
});
NotificationLoaded copyWith({
List<Notif> notif,
bool hasReachedMax,
}) {
return NotificationLoaded(
notif: notif ?? this.notif,
hasReachedMax: hasReachedMax ?? this.hasReachedMax,
);
}
@override
List<Object> get props => [notif, hasReachedMax];
}
class NotificationError extends NotificationState {
String message;
NotificationError({@required this.message});
@override
List<Object> get props => [message];
}
这是我的Notif课
class Notif extends Equatable {
final String notificationId;
final String notificationTitle;
final String notificationBody;
final String notificationDate;
final String notificationTo;
final String notificationImage;
String notificationFlag;
Notif(
{this.notificationId,
this.notificationTitle,
this.notificationBody,
this.notificationDate,
this.notificationTo,
this.notificationImage,
this.notificationFlag});
factory Notif.fromJson(Map<dynamic, dynamic> json) {
return Notif(
notificationId: json['notificationId'] as String,
notificationTitle: json['notificationTitle'] as String,
notificationBody: json['notificationBody'] as String,
notificationDate: json['notificationDate'] as String,
notificationTo: json['notificationTo'] as String,
notificationImage: json['notificationImage'] as String,
notificationFlag: json['notificationFlag'] as String,
);
}
bool operator ==(o) => o is Notif && notificationId == o.notificationId;
int get hashCode => notificationId.hashCode;
}
因此,我将有两个notificationFlag
0或1(均为字符串,这很不好)。因此,在我的CustomAppBar()
中(第一个结构)。我这样做(如下)来读取Notif
的列表中有1个为notificationFlag
state.notif.forEach((f) {
if (f.notificationFlag.toLowerCase().contains("0") ||
f.notificationFlag.contains("0")) {
filteredRecored.add(f);
}
});
对不起,我的英语水平
答案 0 :(得分:0)
这个答案可能是错误的,但是可能将bloc
与Equatable
一起使用?如果是这样,请确保使用Equatable
扩展所有事件和状态,并正确覆盖props
。
@override
List<Object> get props => // Add all the properties of your event or state here
在开发过程中,我发生了很多事情,状态不是由集团触发的。这是由于bloc
跳过了“相同”状态的事实。因此,您需要正确实现Equatable
,以使集团知道您的属性之一实际上是不同的。
例如:
class NotificationLoaded extends Equatable {
final String oneOfYourProperties;
const NotificationLoaded(this.oneOfYourProperties);
@override
List<Object> get props => [this.oneOfYourProperties];
}
编辑:
在这里,我为您提供了如何在Equatable
中正确实现Notif
的实现。我认为operator
和hashcode
声明引起了一些问题。请尝试将您的Notif
代码替换为以下内容:
class Notif extends Equatable {
final String notificationId;
final String notificationTitle;
final String notificationBody;
final String notificationDate;
final String notificationTo;
final String notificationImage;
String notificationFlag;
Notif(
{this.notificationId,
this.notificationTitle,
this.notificationBody,
this.notificationDate,
this.notificationTo,
this.notificationImage,
this.notificationFlag});
factory Notif.fromJson(Map<dynamic, dynamic> json) {
return Notif(
notificationId: json['notificationId'] as String,
notificationTitle: json['notificationTitle'] as String,
notificationBody: json['notificationBody'] as String,
notificationDate: json['notificationDate'] as String,
notificationTo: json['notificationTo'] as String,
notificationImage: json['notificationImage'] as String,
notificationFlag: json['notificationFlag'] as String,
);
}
@override
List<Object> get props => [
this.notificationId,
this.notificationTitle,
this.notificationBody,
this.notificationDate,
this.notificationTo,
this.notificationImage,
this.notificationFlag];
}