matchRoute method
匹配路由
Implementation
AppRouteMatch? matchRoute(String? path) {
if (path == null || path.isEmpty) return null;
String usePath = path;
if (usePath.startsWith("/")) {
usePath = path.substring(1);
}
/// 解析路径
List<String> components = usePath.split("/");
if (path == Navigator.defaultRouteName) {
components = ["/"];
}
Map<RouteTreeNode, RouteTreeNodeMatch> nodeMatches =
<RouteTreeNode, RouteTreeNodeMatch>{};
List<RouteTreeNode> nodesToCheck = _nodes;
/// 循环片段
for (String checkComponent in components) {
Map<RouteTreeNode, RouteTreeNodeMatch> currentMatches =
<RouteTreeNode, RouteTreeNodeMatch>{};
List<RouteTreeNode> nextNodes = <RouteTreeNode>[];
/// 循环要检查的节点
for (RouteTreeNode node in nodesToCheck) {
String pathPart = checkComponent;
Map<String, List<String>>? queryMap;
/// 发现路径带有参数
if (checkComponent.contains("?")) {
/// 分割路径中 路径跟参数
var splitParam = checkComponent.split("?");
pathPart = splitParam[0];
/// 处理参数
queryMap = parseQueryString(splitParam[1]);
}
/// 是否匹配到路径
bool isMatch = (node.part == pathPart || node.isParameter());
if (isMatch) {
RouteTreeNodeMatch? parentMatch = nodeMatches[node.parent];
RouteTreeNodeMatch match =
RouteTreeNodeMatch.fromMatch(parentMatch, node);
if (node.isParameter()) {
String paramKey = node.part.substring(1);
match.parameters[paramKey] = [pathPart];
}
if (queryMap != null) {
match.parameters.addAll(queryMap);
}
// print("matched: ${node.part}, isParam: ${node.isParameter()}, params: ${match.parameters}");
currentMatches[node] = match;
if (node.nodes != null) nextNodes.addAll(node.nodes!);
}
}
nodeMatches = currentMatches;
nodesToCheck = nextNodes;
if (currentMatches.values.length == 0) {
return null;
}
}
List<RouteTreeNodeMatch> matches = nodeMatches.values.toList();
if (matches.length > 0) {
RouteTreeNodeMatch match = matches.first;
RouteTreeNode? nodeToUse = match.node;
// print("using match: ${match}, ${nodeToUse?.part}, ${match?.parameters}");
if (nodeToUse != null &&
nodeToUse.routes != null &&
nodeToUse.routes!.length > 0) {
List<AppRoute> routes = nodeToUse.routes!;
AppRouteMatch routeMatch = AppRouteMatch(routes[0]);
routeMatch.parameters = match.parameters;
return routeMatch;
}
}
return null;
}