back method
dynamic
back(
{ - String? name,
- dynamic result,
- int step = 1,
- bool toInitial = false,
})
Implementation
back({String? name, dynamic result, int step = 1, bool toInitial = false}) async {
/// no route to pop
if (_routes.isEmpty || _routes.length == 1) {
_log('No Route To Pop, Navigation Back Action Ignored');
return;
}
int popCount = 0;
int maxPopCount = _routes.length - 1;
/// if name is provided, pop to the page with the given name
if (name != null) {
int index = _routes.indexWhere((e) => e.name == name);
if (index == -1) {
return _log('No Page Matched :$name, Navigation Back Action Ignored');
}
/// eg: A -> B -> C
/// pop to A
/// _index = 2、 index = 0 and the popCount is 2
popCount = _index - index;
} else {
/// pop count of step
popCount = min(step, maxPopCount);
}
if (toInitial) {
popCount = maxPopCount;
}
if (popCount == 0) {
return;
}
final curRouteId = _routes.last.id;
final curRouteName = _routes.last.name;
/// pop routes
for (int i = popCount; i > 0; i--) {
final route = _routes.removeLast();
route.controller?.onWillDispose();
/// popped multiple routes, only the last route will receive the result
/// eg: A -> B -> C
/// pop to A
/// B and C will not receive the result、 future.catchError will get the [StackRoutePoppedUnexpectedlyException]
if (i == 1 && _routes.last.completer != null && _routes.last.completer!.isCompleted == false) {
/// B : i = 1
debugPrint('_routes.last[${_routes.last.id}] complete with result: $result');
_routes.last.completer?.complete(result);
} else if (i != 1) {
if (route.completer != null && route.completer!.isCompleted == false) {
debugPrint('removed route[${route.id}] complete with cancel');
route.completer?.complete(StackRoutePoppedUnexpectedlyException());
}
}
}
/// emit global navigation event [GBOnStackRouteWillChange] if route did popped
if (curRouteId != _routes.last.id) {
GBOnStackRouteWillChange(
data: GBOnStackRouteWillChangeData(
routeId: curRouteId,
routeName: curRouteName,
targetRouteId: _routes.last.id,
targetRouteName: _routes.last.name,
type: toInitial ? StackRouteChangeType.popTop : StackRouteChangeType.pop,
isInitialRoute: _index == 0,
),
).emit();
if (_index == 0) {
/// emit global navigation event [GBOnStackRouteIsInitial]
GBOnStackRouteIsInitial(data: true).emit();
}
}
/// request rebuild navigator
notifyListeners();
/// notify last route that it's focused
WidgetsBinding.instance.addPostFrameCallback((_) {
_routes.last.controller?.onFocused.call(true);
});
}