我今天的第二个奇怪事件。当我在bloc.dart(库,而不是我的文件)中跟踪调试器时,发现transition.nextState == state && _emitted
是false
时,它不会更新我的小部件(nextState的列表大小为2,状态为10- _emitted为true)。据我了解,构建器应该可以,为什么还有其他地方不能更新?
在我展示代码之前先解释一下逻辑
我在应用启动时获取数据
BlocProvider(create: (context) =>
LogicGraphsPStmntBloc(logicGraphsRepository:
logicGraphsRepository)..add(LogicGraphsNextProblemRequested()),
这将返回10个字符串的列表,并将它们存储在_bloc.dart文件中(不确定这是否是最新技术)
这10个字符串通过状态LogicGraphsPStmntLoadSuccess(statements)
发送,并正确地呈现为按钮
如果单击按钮,则仅显示第一个和所选的字符串。该事件已通过onPressed: () {BlocProvider.of<LogicGraphsPStmntBloc>(context).add(LogicGraphsPStmntCollapsed(statement: index-1));},
这会正确触发状态yield LogicGraphsPStmntLoadSuccess(statementsShown);
,现在列表中仅包含2个元素(与之相比,步骤3中为10个元素),但是不会导致重新呈现
如果我使用调试器进入状态,则可以看到两种状态都有不同数量的元素。
我的状态
abstract class LogicGraphsPStmntState extends Equatable {
const LogicGraphsPStmntState();
@override
List<Object> get props => [];
}
class LogicGraphsPStmntLoadSuccess extends LogicGraphsPStmntState {
const LogicGraphsPStmntLoadSuccess([this.statements = const []]);
final List<String> statements;
@override
List<Object> get props => [];
@override
String toString() => 'LogicGraphsPStmntLoadSuccess { statements: $statements }';
}
我的集团(不完全是,因为未达到my other issue中所述的子函数内部的代码来释放状态。所以目前,我在mapEventToState =
中将这些子函数行作为意大利面条class LogicGraphsPStmntBloc extends Bloc<LogicGraphsPStmntEvent, LogicGraphsPStmntState> {
LogicGraphsPStmntBloc({@required this.logicGraphsRepository}) : super(LogicGraphsPStmntInProgress());
final LogicGraphsRepository logicGraphsRepository;
List<String> statements;
int currentProblem = -1;
@override
Stream<LogicGraphsPStmntState> mapEventToState(LogicGraphsPStmntEvent event) async* {
if (event is LogicGraphsNextProblemRequested) {
_mapLGPStmntNewProblemRequested();
_mapLGPStmntLoadRequested(currentProblem);
}
else if (event is LogicGraphsPStmntLoadRequested) {
_mapLGPStmntLoadRequested(currentProblem);
}
else if (event is LogicGraphsPStmntCollapsed) {
_mapLGPStmntCollapseRequested(event);
}
Stream<LogicGraphsPStmntState> _mapLGPStmntNewProblemRequested() async* {
try {
currentProblem =
await getNextProblem(currentProblem == null ? -1 : currentProblem);
statements =
await logicGraphsRepository.getProblemStmntList(currentProblem);
_mapLGPStmntLoadRequested(currentProblem);
} catch (_) {
yield LogicGraphsPStmntLoadFailure();
}
}
Stream<LogicGraphsPStmntState> _mapLGPStmntLoadRequested(int problem) async* {
try {
yield LogicGraphsPStmntLoadSuccess(statements);
} catch (_) {
yield LogicGraphsPStmntLoadFailure();
}
}
Stream<LogicGraphsPStmntState> _mapLGPStmntCollapseRequested(
LogicGraphsPStmntCollapsed event) async* {
List<String> statementsShown = [];
statementFocussed = event.statement;
statementsShown.add(statements[0]);
statementsShown.add(statements[statementFocussed]);
yield LogicGraphsPStmntLoadSuccess(statementsShown);
}
}
我的小部件
class LogicGraphPage extends StatelessWidget {
final LogicGraphsRepository logicGraphsRepository = LogicGraphsRepository(
logicGraphsApiClient: LogicGraphsApiClient());
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: BlocProvider(
create: (context) =>
LogicGraphsPStmntBloc(logicGraphsRepository: logicGraphsRepository)
..add(LogicGraphsNextProblemRequested()),
child:BlocBuilder<LogicGraphsPStmntBloc, LogicGraphsPStmntState>(
builder: (context, state) {
if (state is LogicGraphsPStmntLoadSuccess) {
final List<String> statements = state.statements;
return ListView.builder(
itemCount: statements.length,
itemBuilder: (BuildContext context, int index) {
return CupertinoButton(
padding: EdgeInsets.all(0),
child: Text(statements[index])
onPressed: () {BlocProvider.of<LogicGraphsPStmntBloc>(context).add(LogicGraphsPStmntCollapsed(statement: index-1));},
);
});
}
else return Container();
}
)
),
);
}
}
在bloc.dart库中的函数,我假设发出了新状态。您会看到if (transition.nextState == state && _emitted) return;
行。下一个状态有2个元素,状态有10个,_emitted为true,所以我假设代码继续。而是触发返回,并跳过带有emit(transition.nextState);
的行。
任何帮助都将受到高度赞赏,因为这是我第一次接触BLoC / equableable,而且颤动对我来说还是很新的。但是我正在进步!
void _bindEventsToStates() {
_transitionSubscription = transformTransitions(
transformEvents(
_eventController.stream,
(event) => mapEventToState(event).map(
(nextState) => Transition(
currentState: state,
event: event,
nextState: nextState,
),
),
),
).listen(
(transition) {
if (transition.nextState == state && _emitted) return; // <<<<<<<<<<<
try {
onTransition(transition);
emit(transition.nextState);
} on dynamic catch (error, stackTrace) {
onError(error, stackTrace);
}
_emitted = true;
},
onError: onError,
);
}
答案 0 :(得分:2)
我想集团无法分辨LogicGraphsPStmntLoadSuccess(statements)
和LogicGraphsPStmntLoadSuccess(statementsShown)
之间的差异,因为它们是相同的状态,并且我认为它无法发现不同参数之间的差异。
所以我建议这样做:
在产生LogicGraphsPStmntLoadSuccess(statementsShown)
之前,请尝试产生“切换”状态,例如之前我不知道LogicGraphsPStmntChangeStatement
。
所以:
yield LogicGraphsPStmntChangeStatement;
yield LogicGraphsPStmntLoadSuccess(statementsShown);
应该可以解决问题。