matchRoute method

AppRouteMatch? matchRoute(
  1. String? path
)

匹配路由

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;
}