switch img angular angular2-routing guard

img - Guardias angulares, declaración poco clara en los documentos.



ng-src angular 5 (2)

Cuando piensas en enrutar, cuanto más profundo vayas al árbol, más específico te vuelves.

Por ejemplo:

/food-types/sweets/pies/blueberry

Entonces, cuando le dices a Angular que quieres CanDeactivate del CanDeactivate de arándanos, primero verifica CanDeactivate en blueberry, porque estás retrocediendo por el árbol de navegación, a una ubicación diferente. CanActivateChild también caminará por el árbol hacia el camino del niño, según mi entendimiento, por la misma razón: primero quiere verificar los niveles más profundos, para verificar que sus hijos puedan activarse.

Lo contrario es cierto de CanActivate . Cuando le dices a Angular que quieres ver el pastel de blueberry , estás caminando por el árbol y, por lo tanto, verifica la guardia en orden a medida que baja por el árbol.

Estoy tratando de entender profundamente el ángulo, así que leí los documentos y fue muy útil.
Ahora estoy estudiando a los guardias. Y leí esta declaración en los documentos.

El enrutador verifica primero los guardias CanDeactivate y CanActivateChild, desde la ruta secundaria más profunda hasta la cima. Luego verifica los guardias CanActivate de arriba hacia abajo hasta la ruta secundaria más profunda.

ahora estoy confundido, ¿por qué angular lo realiza de esta manera?
¿Hay algún beneficio de hacer la comprobación desde el niño más profundo hasta la cima para CanDeactivate & CanActivateChild ? y de arriba a la ruta infantil más profunda para CanActivate ?


Intenté creer lo que escribí en el sitio de documentos. Sin embargo, parece que no es del todo correcto, o la implementación se ha actualizado pero docs no se actualiza.

Ser breve:

Primero, CanDeactivate guardas de CanDeactivate se verifican de lo más profundo a lo más alto y CanActivate guardias de CanActivate se CanActivate de arriba a lo más profundo (se cerrará con la verificación falsa en el recorrido).

En segundo lugar, los guardias de CanActivateChild no se verifican desde lo más profundo hasta lo más alto .

TL; DR

Explicación detallada

Debemos comprobar la fuente para ver cómo funciona.

Nota: la confirmación verificada es: https://github.com/angular/angular/tree/edb8375a5ff15d77709ccf1759efb14091fa86a4

paso 1 - ver cuando se llamó a CanActivateChild

fuente aquí L929 .

Este es solo el lugar runCanActivateChild se llamó a su llamador superior runCanActivateChild .

En esa línea, podemos obtener algún indicio de que hace el mismo truco que CanActivate , ya que se llama después a la llamada superior de runCanActivate .

paso 2 - ver cómo funciona runCanActivateChild

L926 y L950 .

runCanActivateChild se llamó dentro de la iteración de canActivateChecks , igual que cómo se llamó runCanActivate . Aquí sabemos que CanActivate (me refiero a la función) y CanActivateChild comparten la misma fuente de datos: canActivateChecks .

Paso 3: ¿Qué es canActivateChecks y cómo se procesa?

Entonces, ¿qué es canActivateChecks ? Obviamente, podemos descubrir que es una matriz de instancias de clase CanActivate . Pero, ¿cómo se asigna canActivateChecks ? Vaya a aquí L865 . Esta es la parte importante, así que los voy a pegar aquí.

private traverseChildRoutes( futureNode: TreeNode<ActivatedRouteSnapshot>, currNode: TreeNode<ActivatedRouteSnapshot>|null, contexts: ChildrenOutletContexts|null, futurePath: ActivatedRouteSnapshot[]): void { const prevChildren = nodeChildrenAsMap(currNode); // Process the children of the future route futureNode.children.forEach(c => { this.traverseRoutes(c, prevChildren[c.value.outlet], contexts, futurePath.concat([c.value])); delete prevChildren[c.value.outlet]; }); // Process any children left from the current route (not active for the future route) forEach( prevChildren, (v: TreeNode<ActivatedRouteSnapshot>, k: string) => this.deactivateRouteAndItsChildren(v, contexts !.getContext(k))); } private traverseRoutes( futureNode: TreeNode<ActivatedRouteSnapshot>, currNode: TreeNode<ActivatedRouteSnapshot>, parentContexts: ChildrenOutletContexts|null, futurePath: ActivatedRouteSnapshot[]): void { const future = futureNode.value; const curr = currNode ? currNode.value : null; const context = parentContexts ? parentContexts.getContext(futureNode.value.outlet) : null; // reusing the node if (curr && future._routeConfig === curr._routeConfig) { if (this.shouldRunGuardsAndResolvers( curr, future, future._routeConfig !.runGuardsAndResolvers)) { this.canActivateChecks.push(new CanActivate(futurePath)); const outlet = context !.outlet !; this.canDeactivateChecks.push(new CanDeactivate(outlet.component, curr)); } else { // we need to set the data future.data = curr.data; future._resolvedData = curr._resolvedData; } // If we have a component, we need to go through an outlet. if (future.component) { this.traverseChildRoutes( futureNode, currNode, context ? context.children : null, futurePath); // if we have a componentless route, we recurse but keep the same outlet map. } else { this.traverseChildRoutes(futureNode, currNode, parentContexts, futurePath); } } else { // ##### comment by e-cloud ##### if (curr) { this.deactivateRouteAndItsChildren(currNode, context); } this.canActivateChecks.push(new CanActivate(futurePath)); // If we have a component, we need to go through an outlet. if (future.component) { this.traverseChildRoutes(futureNode, null, context ? context.children : null, futurePath); // if we have a componentless route, we recurse but keep the same outlet map. } else { this.traverseChildRoutes(futureNode, null, parentContexts, futurePath); } } }

Es un poco largo Pero si lo atraviesas, descubrirás que juega una profundidad de primer recorrido . Vamos a ignorar el mismo cambio de ruta. Busque el ##### comment by e-cloud ##### y vea el procedimiento principal. Muestra que primero actualiza canActivateChecks luego realiza el siguiente nivel de travesía (Pre-order transversal en su totalidad).

Debe saber que el enrutador trata todas las rutas de la aplicación como un árbol de url. Cada PreActivation divide su future (como una ruta de árbol) en segmentos de ruta por el recorrido.

Tomemos un ejemplo simplificado :

Tenemos la ruta futura como /a/b/c .
Luego obtendremos [''/ a'', ''/ a / b'', ''/ a / b / c''] como canActivateChecks

Aparentemente, canActivateChecks representa las rutas de la parte superior a la más profunda del future La fuente muestra que canActivateChecks se itera de izquierda a derecha.

paso 4 - conclusión

podemos concluir que CanActivateChild se ejecuta desde la parte superior hasta el niño más profundo.

Espero que lo explique claramente.