警告:发布的所有内容都是为了提醒或维护我的知识,我希望它也能在您的学习之旅中有所帮助。这个想法是,当您有时间时,在同一篇文章中添加与该主题相关的信息,使其完整且始终最新。
如果您发现帖子中存在任何缺陷或发现缺少某些内容,请帮助我改进:)
当我与开发人员互动并为其提供支持时,我注意到技术债务并尝试支持知识的发展。根据我的拙见,我选择关注那些每天给开发人员带来最大痛苦和困难的点。
这些困难之一是 Angular 的路由功能。
因此,除了一些现有的功能之外,我们还来谈谈 Angular 的导航模块是如何工作的。
Angular 用于路由应用程序的分步过程的简要总结:
在底层,Angular、React 或 Vue 使用 History API。
历史记录是一个浏览器界面,允许您操纵用户的浏览历史记录而无需重新加载页面。它是随 HTML5 规范引入的,并提供了一组用于在浏览器历史记录中添加、修改或删除条目以及响应浏览状态变化的方法。
参见:
请注意,每次更改路线时,都会填充“历史记录”对象并标识新路线。
使用位置和路由器时都会发生这种情况:
_import { Location } from "@angular/common"_ _import { Router } from "@angular/router"_
发生这种情况是因为每次我们导航到任何路线时,都会调用 history.pushState 方法。同样,每次我们使用 replaceUrl.
时,history.replaceState 方法都会被调用一个重要的观察是,虽然History API可以满足最基本的需求,但从我们进入SPA监控主题的那一刻起,我们发现它存在一些问题。为了解决这些问题,一个替代这个 API 的新提案正在进行中,这就是 Navigation API。它仍处于实验阶段,我们将在有关 SPA 监控和性能的帖子中详细讨论它。
SPA 前端有 2 种最常见的路由策略:
HashLocationStrategy(哈希模式)和 PathLocationStrategy(历史模式)。
对于那些已经每天使用 SPA 的人来说,您知道这两种策略之间最基本的区别:
“干净”URL:URL 遵循传统的 Web 导航模式,没有任何 #。例如,/home、/about。
示例 URL:https://example.com/home。
哈希 URL:URL 包含 # 和后跟路径。 # 后面的内容不会发送到服务器,完全由浏览器处理。
示例 URL:https://example.com/#/home.
关于每种方法的最佳用途存在一些争论。有些人评论了仅在 SSR 架构中使用 HashLocation 的策略,而另一些人则理解它带来了更多简单性,因此在所有场景中都使用它,但我不会详细讨论。如果您有兴趣了解有关讨论的更多信息,这里有一个提示。
Lembra do que comentamos lá em cima sobre a History API?
O que essa opção faz é garantir que o conteúdo seja renderizado na tela, mas sem acionar o método history.pushstate que é responsável por definir a URL do navegador. Só o status interno do Router que será atualizado.
Repare que,
o history.state possui tamanho == 1
E quando navego para uma próxima rota com o skipLocation ativo(
this.router.navigate(['componentA'], {skipLocationChange: true});
), ele não altera a url e nem o estado da api de histórico
no entanto, quando acessamos os eventos que o router emite, é possível ver que o estado interno do Router está atualizado
Método disponibilizado para permitir executar uma determinada ação antes do componentes ser carregado. Na imagem abaixo, eu mostro que o resolver é carregado primeiro, depois o componente é carregado e a informação é lida:
Exemplo de código
Crie o resolver:
@Injectable({ providedIn: 'root' }) export class TestResolver implements Resolve<string> { resolve(): Observable<string> { return of('string retornada pelo resolver'); } }
Declare-o no arquivo de rotas:
{path: 'componentB', component: ComponentB, resolve: { testResolve: TestResolver} }
Receba os parâmetros no componente:
export class ComponentB { constructor(private router: Router, private activatedRoute: ActivatedRoute) { this.activatedRoute.data.subscribe(res => { console.log(res); }) }
Há outras formas de lidar com o problema que os "resolvers" se propõem a sanar. Lembre-se que resolver atua de forma síncrona. Ou seja, para que o componente seja carregado, primeiro o resolver terá que finalizar seu processamento. Isso pode levar a segundos de espera por parte do cliente e a usabilidade da aplicação não ficar tão interessante. Há um tópico bem interessa sobre o uso de resolvers e que você pode conferir aqui.
define quando executar guards e resolvers. Você que utilizou algum guard ou resolver, já deve ter se perguntando se daria pra poder acioná-los só após uma mudança de parâmetros na rota ou de queryParams ou algum outro customizado. Saiba que é possível, utilizando o runGuardsAndResolvers.
Pode declarar direto no arquivo de rotas:
{ path: 'example', component: ExampleComponent, resolve: { data: ExampleResolver }, canActivate: [AuthGuard], runGuardsAndResolvers: 'paramsOrQueryParamsChange' // Define quando executar guards e resolvers }
Você possui essas opções:
'pathParamsChange' | 'pathParamsOrQueryParamsChange' | 'paramsChange' | 'paramsOrQueryParamsChange' | 'always' | ((from: ActivatedRouteSnapshot, to: ActivatedRouteSnapshot) => boolean);
O método forRoot() configura o roteador no nível raiz da aplicação e disponibiliza todas as funcionalidades de roteamento. Com essa configuração, o angula saberá como gerenciar as rotas definidas e as diretivas de roteamento. É com base na declaração do forRoot que routerOutlet, routerLink e outros ficam disponíveis dentro da aplicação.
routerLink é uma diretiva usada para definir links de navegação.
e permite a navegação programática entre as diferentes rotas da aplicação. Quando clicado, o link navega para a rota especificada sem recarregar a página inteira.
Sintaxe: [routerLink]="['/path']"
routerLinkActive é uma diretiva usada para adicionar uma classe CSS ao elemento quando a rota associada está ativa, facilitando a aplicação de estilos ou classes diferentes aos links de navegação que correspondem à rota atualmente ativa, permitindo destacar visualmente o link ativo.
Exemplo:
<style> .classRouterLinkActive { color: blue; } </style> <button class="color" routerLinkActive="classRouterLinkActive" [routerLink]="['/componentA']">click here A</button> <button class="color" routerLinkActive="classRouterLinkActive" routerLink='/componentB'>click here B</button> <button class="color" routerLinkActive="classRouterLinkActive" routerLink='/componentE'>click here E</button>
Veja que quando a rota está ativa, a classe é imediatamente aplicada:
serviço disponibilizado que sempre retorna os dados da rota ativa no momento.
Ao declarar dentro do componente, você vai sempre obter os dados atuais relativos a rota do componente em que está sendo importado:
constructor(private router: Router, private activatedRoute: ActivatedRoute) { console.log(activatedRoute); }
O redirectTo, possui duas formas de realizar o roteamento: relativa e absoluta.
De acordo com a forma que você chama a rota:
a diferença é que ao usar um caminho absoluto, a busca pelo próximo objeto de configuração começará da raiz, ou seja, o primeiro array de rotas mais externo.
Enquanto que ao usar um caminho relativo, a pesquisa começará na primeira rota na matriz de onde a operação de redirecionamento começou.
relativo:
const routes: Routes = [ {path: 'componentA', component: ComponentA}, {path: 'componentB', component: ComponentB, children: [ { path: 'componentC', redirectTo: 'componentA' }, { path: 'componentA', component: ComponentA }, ] } ];
Ao usar dessa forma, quando eu estou no componentB, ele direcionará pro componentA, filho de B, formando assim a rota: "componentB/componentA"
Absoluto:
const routes: Routes = [ {path: 'componentA', component: ComponentA}, {path: 'componentB', component: ComponentB, children: [ { path: 'componentC', redirectTo: '/componentA' }, { path: 'componentA', component: ComponentA }, ] } ];
Já quando colocamos a barra("/"), ele começar a busca pelo raíz do arquivo de rotas e direcionará pro componentA da raíz:
Eu espero que tenha gostado e te ajudado a melhor a compreensão de algo ou até mesmo aberto caminhos para novos conhecimentos. Conto com você nas críticas e sugestões para irmos melhorando o conteúdo e mantendo sempre atualizado para a comunidade.
以上是角度路由器的详细内容。更多信息请关注PHP中文网其他相关文章!