Adicionar navegação e roteamento navigation-routing
- O editor universal para editar conteúdo headless visualmente.
- O editor de fragmentos de conteúdo para editar conteúdo headless com base em formulários.
Saiba como várias exibições no SPA são compatíveis usando as Páginas do AEM e o SDK do Editor de SPA. A navegação dinâmica é implementada usando rotas do Angular e adicionada a um componente de Cabeçalho existente.
Objetivo
- Entenda as opções de roteamento de modelo SPA disponíveis ao usar o Editor SPA.
- Saiba como usar o roteamento de Angular para navegar entre diferentes exibições do SPA.
- Implemente uma navegação dinâmica orientada pela hierarquia de páginas do AEM.
O que você vai criar
Este capítulo adiciona um menu de navegação a um componente Header existente. O menu de navegação é orientado pela hierarquia de páginas do AEM e usa o modelo JSON fornecido pelo Componente Principal de Navegação.
Pré-requisitos
Revise as ferramentas e instruções necessárias para configurar um ambiente de desenvolvimento local.
Obter o código
-
Baixe o ponto de partida para este tutorial pelo Git:
code language-shell $ git clone git@github.com:adobe/aem-guides-wknd-spa.git $ cd aem-guides-wknd-spa $ git checkout Angular/navigation-routing-start -
Implante a base de código em uma instância do AEM local usando Maven:
code language-shell $ mvn clean install -PautoInstallSinglePackageSe estiver usando o AEM 6.x, adicione o perfil
classic:code language-shell $ mvn clean install -PautoInstallSinglePackage -Pclassic -
Instale o pacote concluído para o site de referência WKND tradicional. As imagens fornecidas pelo site de referência WKND são reutilizadas no SPA do WKND. O pacote pode ser instalado usando o Gerenciador de Pacotes da AEM.
do Gerenciador de Pacotes
Você sempre pode exibir o código concluído em GitHub ou verificar o código localmente alternando para a ramificação Angular/navigation-routing-solution.
Inspecionar atualizações de HeaderComponent inspect-header
Nos capítulos anteriores, o componente HeaderComponent foi adicionado como um componente puro do Angular incluído via app.component.html. Neste capítulo, o componente HeaderComponent é removido do aplicativo e adicionado por meio do Editor de Modelos. Isso permite que os usuários configurem o menu de navegação do HeaderComponent no AEM.
-
No IDE de sua escolha, abra o projeto inicial de SPA para este capítulo.
-
Abaixo do módulo
ui.frontend, inspecione o arquivoheader.component.tsem:ui.frontend/src/app/components/header/header.component.ts.Várias atualizações foram feitas, incluindo a adição de um
HeaderEditConfige umMapTopara habilitar o componente a ser mapeado para um componente AEMwknd-spa-angular/components/header.code language-js /* header.component.ts */ ... const HeaderEditConfig = { ... }; @Component({ selector: 'app-header', templateUrl: './header.component.html', styleUrls: ['./header.component.scss'] }) export class HeaderComponent implements OnInit { @Input() items: object[]; ... } ... MapTo('wknd-spa-angular/components/header')(withRouter(Header), HeaderEditConfig);Anote a anotação
@Input()paraitems.itemsconterá uma matriz de objetos de navegação passados do AEM. -
No módulo
ui.apps, inspecione a definição do componenteHeaderdo AEM:ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/header/.content.xml:code language-xml <?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" jcr:primaryType="cq:Component" jcr:title="Header" sling:resourceSuperType="wknd-spa-angular/components/navigation" componentGroup="WKND SPA Angular - Structure"/>O componente
Headerdo AEM herdará toda a funcionalidade do Componente principal de navegação por meio da propriedadesling:resourceSuperType.
Adicionar o componente de cabeçalho ao modelo SPA add-header-template
-
Abra um navegador e faça logon no AEM, http://localhost:4502/. A base de código inicial já deve estar implantada.
-
Navegue até o Modelo de página do SPA: http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-page-template/structure.html.
-
Selecione o Contêiner de Layout Raiz mais externo e clique em seu ícone Política. Tenha cuidado não para selecionar o Contêiner de layout desbloqueado para criação.
-
Copie a política atual e crie uma nova política chamada Estrutura do SPA:
Em Componentes Permitidos > Geral > selecione o componente Contêiner de Layout.
Em Componentes Permitidos > WKND SPA ANGULAR - STRUCTURE > selecione o componente Cabeçalho:
Em Componentes Permitidos > WKND SPA ANGULAR - Conteúdo > selecione os componentes Imagem e Texto. Você deve ter um total de quatro componentes selecionados.
Clique em Concluído para salvar as alterações.
-
Atualizar a página. Adicione o componente Cabeçalho acima do Contêiner de Layout desbloqueado:
-
Selecione o componente Cabeçalho e clique em seu ícone Política para editar a política.
-
Crie uma nova política com um Título da Política de "Cabeçalho WKND SPA".
Em Propriedades:
- Defina a Raiz de Navegação como
/content/wknd-spa-angular/us/en. - Defina os Excluir Níveis de Raiz para 1.
- Desmarcar Coletar todas as páginas secundárias.
- Defina a Profundidade da Estrutura de Navegação como 3.
Isso coletará os 2 níveis de navegação abaixo de
/content/wknd-spa-angular/us/en. - Defina a Raiz de Navegação como
-
Depois de salvar as alterações, você deverá ver o
Headerpreenchido como parte do modelo:
Criar páginas secundárias
Em seguida, crie páginas adicionais no AEM que servirão como as diferentes exibições no SPA. Também inspecionaremos a estrutura hierárquica do modelo JSON fornecido pelo AEM.
-
Navegue até o console Sites: http://localhost:4502/sites.html/content/wknd-spa-angular/us/en/home. Selecione a Página Inicial do WKND SPA Angular e clique em Criar > Página:
-
Em Modelo, selecione Página de SPA. Em Propriedades, digite "Página 1" para o Título e "página-1" como o nome.
Clique em Criar e, no pop-up da caixa de diálogo, clique em Abrir para abrir a página no Editor SPA do AEM.
-
Adicionar um novo componente Texto ao Contêiner de Layout principal. Edite o componente e insira o texto: "Página 1" usando o RTE e o elemento H1 (você terá que entrar no modo de tela cheia para alterar os elementos de parágrafo)
Fique à vontade para adicionar mais conteúdo, como uma imagem.
-
Retorne ao console do AEM Sites e repita as etapas acima, criando uma segunda página denominada "Página 2" como irmã da Página 1. Adicionar conteúdo à Página 2 para identificá-lo facilmente.
-
Por fim, crie uma terceira página, "Página 3", mas como criança da Página 2. Depois de concluída, a hierarquia do site deve ser semelhante ao seguinte:
-
Em uma nova guia, abra a API do modelo JSON fornecida pelo AEM: http://localhost:4502/content/wknd-spa-angular/us/en.model.json. Esse conteúdo JSON é solicitado quando o SPA é carregado pela primeira vez. A estrutura externa tem a seguinte aparência:
code language-json { "language": "en", "title": "en", "templateName": "spa-app-template", "designPath": "/libs/settings/wcm/designs/default", "cssClassNames": "spa page basicpage", ":type": "wknd-spa-angular/components/spa", ":items": {}, ":itemsOrder": [], ":hierarchyType": "page", ":path": "/content/wknd-spa-angular/us/en", ":children": { "/content/wknd-spa-angular/us/en/home": {}, "/content/wknd-spa-angular/us/en/home/page-1": {}, "/content/wknd-spa-angular/us/en/home/page-2": {}, "/content/wknd-spa-angular/us/en/home/page-2/page-3": {} } }Em
:childrenvocê deve ver uma entrada para cada uma das páginas criadas. O conteúdo de todas as páginas está nesta solicitação JSON inicial. Depois que o roteamento de navegação é implementado, as exibições subsequentes do SPA são carregadas rapidamente, pois o conteúdo já está disponível no lado do cliente.Não é recomendável carregar TODOS do conteúdo de um SPA na solicitação JSON inicial, pois isso retardaria o carregamento da página inicial. Em seguida, vamos analisar como a profundidade da hierarquia das páginas é coletada.
-
Navegue até o modelo Raiz do SPA em: http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-app-template/structure.html.
Clique no menu Propriedades da página > Política da página:
-
O modelo Raiz de SPA tem uma guia Estrutura Hierárquica extra para controlar o conteúdo JSON coletado. A Profundidade da Estrutura determina a profundidade na hierarquia do site para coletar páginas secundárias abaixo da raiz. Você também pode usar o campo Padrões de estrutura para filtrar páginas adicionais com base em uma expressão regular.
Atualize a Profundidade da Estrutura para "2":
Clique em Concluído para salvar as alterações na política.
-
Reabra o modelo JSON http://localhost:4502/content/wknd-spa-angular/us/en.model.json.
code language-json { "language": "en", "title": "en", "templateName": "spa-app-template", "designPath": "/libs/settings/wcm/designs/default", "cssClassNames": "spa page basicpage", ":type": "wknd-spa-angular/components/spa", ":items": {}, ":itemsOrder": [], ":hierarchyType": "page", ":path": "/content/wknd-spa-angular/us/en", ":children": { "/content/wknd-spa-angular/us/en/home": {}, "/content/wknd-spa-angular/us/en/home/page-1": {}, "/content/wknd-spa-angular/us/en/home/page-2": {} } }Observe que o caminho Página 3 foi removido:
/content/wknd-spa-angular/us/en/home/page-2/page-3do modelo JSON inicial.Posteriormente, observaremos como o SDK do Editor SPA do AEM pode carregar dinamicamente conteúdo adicional.
Implementar a navegação
Em seguida, implemente o menu de navegação com um novo NavigationComponent. Podemos adicionar o código diretamente em header.component.html, mas uma prática recomendada é evitar componentes grandes. Em vez disso, implemente um NavigationComponent que possa ser reutilizado posteriormente.
-
Revise o JSON exposto pelo componente
Headerdo AEM em http://localhost:4502/content/wknd-spa-angular/us/en.model.json:code language-json ... "header": { "items": [ { "level": 0, "active": true, "path": "/content/wknd-spa-angular/us/en/home", "description": null, "url": "/content/wknd-spa-angular/us/en/home.html", "lastModified": 1589062597083, "title": "WKND SPA Angular Home Page", "children": [ { "children": [], "level": 1, "active": false, "path": "/content/wknd-spa-angular/us/en/home/page-1", "description": null, "url": "/content/wknd-spa-angular/us/en/home/page-1.html", "lastModified": 1589429385100, "title": "Page 1" }, { "level": 1, "active": true, "path": "/content/wknd-spa-angular/us/en/home/page-2", "description": null, "url": "/content/wknd-spa-angular/us/en/home/page-2.html", "lastModified": 1589429603507, "title": "Page 2", "children": [ { "children": [], "level": 2, "active": false, "path": "/content/wknd-spa-angular/us/en/home/page-2/page-3", "description": null, "url": "/content/wknd-spa-angular/us/en/home/page-2/page-3.html", "lastModified": 1589430413831, "title": "Page 3" } ], } ] } ], ":type": "wknd-spa-angular/components/header"A natureza hierárquica das páginas do AEM é modelada no JSON que pode ser usado para preencher um menu de navegação. Lembre-se de que o componente
Headerherda toda a funcionalidade do Componente principal de Navegação e o conteúdo exposto por meio do JSON é mapeado automaticamente para a anotação@Inputdo Angular. -
Abra uma nova janela de terminal e navegue até a pasta
ui.frontenddo projeto de SPA. Crie um novoNavigationComponentusando a ferramenta Angular CLI:code language-shell $ cd ui.frontend $ ng generate component components/navigation CREATE src/app/components/navigation/navigation.component.scss (0 bytes) CREATE src/app/components/navigation/navigation.component.html (25 bytes) CREATE src/app/components/navigation/navigation.component.spec.ts (656 bytes) CREATE src/app/components/navigation/navigation.component.ts (286 bytes) UPDATE src/app/app.module.ts (2032 bytes) -
Em seguida, crie uma classe chamada
NavigationLinkusando a CLI do Angular no diretóriocomponents/navigationrecém-criado:code language-shell $ cd src/app/components/navigation/ $ ng generate class NavigationLink CREATE src/app/components/navigation/navigation-link.spec.ts (187 bytes) CREATE src/app/components/navigation/navigation-link.ts (32 bytes) -
Retorne ao IDE de sua escolha e abra o arquivo em
navigation-link.tsem/src/app/components/navigation/navigation-link.ts.
-
Popular
navigation-link.tscom o seguinte:code language-js export class NavigationLink { title: string; path: string; url: string; level: number; children: NavigationLink[]; active: boolean; constructor(data) { this.path = data.path; this.title = data.title; this.url = data.url; this.level = data.level; this.active = data.active; this.children = data.children.map( item => { return new NavigationLink(item); }); } }É uma classe simples para representar um link de navegação individual. No construtor de classe, esperamos que
dataseja o objeto JSON transmitido do AEM. Essa classe é usada emNavigationComponenteHeaderComponentpara preencher facilmente a estrutura de navegação.Nenhuma transformação de dados é executada, essa classe é criada principalmente para digitar o modelo JSON. Observe que
this.childrené digitado comoNavigationLink[]e que o construtor cria recursivamente novos objetosNavigationLinkpara cada um dos itens na matrizchildren. Lembre-se de que o modelo JSON paraHeaderé hierárquico. -
Abra o arquivo
navigation-link.spec.ts. Este é o arquivo de teste para a classeNavigationLink. Atualize-o com o seguinte:code language-js import { NavigationLink } from './navigation-link'; describe('NavigationLink', () => { it('should create an instance', () => { const data = { children: [], level: 1, active: false, path: '/content/wknd-spa-angular/us/en/home/page-1', description: null, url: '/content/wknd-spa-angular/us/en/home/page-1.html', lastModified: 1589429385100, title: 'Page 1' }; expect(new NavigationLink(data)).toBeTruthy(); }); });Observe que
const datasegue o mesmo modelo JSON inspecionado anteriormente para um único link. Isso está longe de ser um teste de unidade robusto, no entanto, deve ser suficiente para testar o construtor deNavigationLink. -
Abra o arquivo
navigation.component.ts. Atualize-o com o seguinte:code language-js import { Component, OnInit, Input } from '@angular/core'; import { NavigationLink } from './navigation-link'; @Component({ selector: 'app-navigation', templateUrl: './navigation.component.html', styleUrls: ['./navigation.component.scss'] }) export class NavigationComponent implements OnInit { @Input() items: object[]; constructor() { } get navigationLinks(): NavigationLink[] { if (this.items && this.items.length > 0) { return this.items.map(item => { return new NavigationLink(item); }); } return null; } ngOnInit() {} }NavigationComponentespera umobject[]chamadoitemsque seja o modelo JSON do AEM. Esta classe expõe um único métodoget navigationLinks()que retorna uma matriz deNavigationLinkobjetos. -
Abra o arquivo
navigation.component.htmle atualize-o com o seguinte:code language-html <ul *ngIf="navigationLinks && navigationLinks.length > 0" class="navigation__group"> <ng-container *ngTemplateOutlet="recursiveListTmpl; context:{ links: navigationLinks }"></ng-container> </ul>Isso gera um
<ul>inicial e chama o métodoget navigationLinks()denavigation.component.ts. Um<ng-container>é usado para fazer uma chamada para um modelo chamadorecursiveListTmple passar onavigationLinkscomo uma variável chamadalinks.Adicionar o
recursiveListTmplem seguida:code language-html <ng-template #recursiveListTmpl let-links="links"> <li *ngFor="let link of links" class="{{'navigation__item navigation__item--' + link.level}}"> <a [routerLink]="link.url" class="navigation__item-link" [title]="link.title" [attr.aria-current]="link.active"> {{link.title}} </a> <ul *ngIf="link.children && link.children.length > 0"> <ng-container *ngTemplateOutlet="recursiveListTmpl; context:{ links: link.children }"></ng-container> </ul> </li> </ng-template>Aqui, o restante da renderização do link de navegação é implementado. Observe que a variável
linké do tipoNavigationLinke todos os métodos/propriedades criados por essa classe estão disponíveis.[routerLink]é usado em vez do atributohrefnormal. Isso nos permite vincular a rotas específicas no aplicativo, sem uma atualização de página inteira.A parte recursiva da navegação também é implementada com a criação de outro
<ul>se olinkatual tiver uma matrizchildrennão vazia. -
Atualize
navigation.component.spec.tspara adicionar suporte aRouterTestingModule:code language-diff ... + import { RouterTestingModule } from '@angular/router/testing'; ... beforeEach(async(() => { TestBed.configureTestingModule({ + imports: [ RouterTestingModule ], declarations: [ NavigationComponent ] }) .compileComponents(); })); ...É necessário adicionar
RouterTestingModuleporque o componente usa[routerLink]. -
Atualize
navigation.component.scsspara adicionar alguns estilos básicos aNavigationComponent:
@import "~src/styles/variables";
$link-color: $black;
$link-hover-color: $white;
$link-background: $black;
:host-context {
display: block;
width: 100%;
}
.navigation__item {
list-style: none;
}
.navigation__item-link {
color: $link-color;
font-size: $font-size-large;
text-transform: uppercase;
padding: $gutter-padding;
display: flex;
border-bottom: 1px solid $gray;
&:hover {
background: $link-background;
color: $link-hover-color;
}
}
Atualizar o componente de cabeçalho
Agora que o NavigationComponent foi implementado, o HeaderComponent deve ser atualizado para fazer referência a ele.
-
Abra um terminal e navegue até a pasta
ui.frontendno projeto do SPA. Inicie o servidor de desenvolvimento do webpack:code language-shell $ npm start -
Abra uma guia do navegador e navegue até http://localhost:4200/.
O servidor de desenvolvimento do webpack deve ser configurado para usar o proxy do modelo JSON de uma instância local do AEM (
ui.frontend/proxy.conf.json). Isso nos permitirá codificar diretamente em relação ao conteúdo criado no AEM a partir de versões anteriores do tutorial.
Atualmente, o
HeaderComponentjá tem a funcionalidade de alternância de menu implementada. Em seguida, adicione o componente de navegação. -
Retorne ao IDE de sua escolha e abra o arquivo
header.component.tsemui.frontend/src/app/components/header/header.component.ts. -
Atualize o método
setHomePage()para remover a String codificada e usar as props dinâmicas transmitidas pelo componente AEM:code language-js /* header.component.ts */ import { NavigationLink } from '../navigation/navigation-link'; ... setHomePage() { if (this.hasNavigation) { const rootNavigationLink: NavigationLink = new NavigationLink(this.items[0]); this.isHome = rootNavigationLink.path === this.route.snapshot.data.path; this.homePageUrl = rootNavigationLink.url; } } ...Uma nova instância de
NavigationLinké criada com base emitems[0], a raiz do modelo JSON de navegação transmitido pelo AEM.this.route.snapshot.data.pathretorna o caminho da rota atual do Angular. Este valor é usado para determinar se a rota atual é a Página Inicial.this.homePageUrlé usado para preencher o link de âncora no logotipo. -
Abra
header.component.htmle substitua o espaço reservado estático para a navegação por uma referência aoNavigationComponentrecém-criado:code language-diff <div class="header-navigation"> <div class="navigation"> - Navigation Placeholder + <app-navigation [items]="items"></app-navigation> </div> </div>O atributo
[items]=itemspassa o@Input() itemsdeHeaderComponentparaNavigationComponent, onde ele compilará a navegação. -
Abra
header.component.spec.tse adicione uma declaração paraNavigationComponent:code language-diff /* header.component.spect.ts */ + import { NavigationComponent } from '../navigation/navigation.component'; describe('HeaderComponent', () => { let component: HeaderComponent; let fixture: ComponentFixture<HeaderComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ RouterTestingModule ], + declarations: [ HeaderComponent, NavigationComponent ] }) .compileComponents(); }));Como o
NavigationComponentagora é usado como parte doHeaderComponent, ele precisa ser declarado como parte da base de testes. -
Salve as alterações nos arquivos abertos e retorne ao servidor de desenvolvimento do webpack: http://localhost:4200/
Abra a navegação clicando na opção de menu e você verá os links de navegação preenchidos. Você deve conseguir navegar para diferentes exibições do SPA.
Entender o roteamento SPA
Agora que a navegação foi implementada, inspecione o roteamento no AEM.
-
No IDE, abra o arquivo
app-routing.module.tsemui.frontend/src/app.code language-js /* app-routing.module.ts */ import { AemPageDataResolver, AemPageRouteReuseStrategy } from '@adobe/cq-angular-editable-components'; import { NgModule } from '@angular/core'; import { RouteReuseStrategy, RouterModule, Routes, UrlMatchResult, UrlSegment } from '@angular/router'; import { PageComponent } from './components/page/page.component'; export function AemPageMatcher(url: UrlSegment[]): UrlMatchResult { if (url.length) { return { consumed: url, posParams: { path: url[url.length - 1] } }; } } const routes: Routes = [ { matcher: AemPageMatcher, component: PageComponent, resolve: { path: AemPageDataResolver } } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], providers: [ AemPageDataResolver, { provide: RouteReuseStrategy, useClass: AemPageRouteReuseStrategy } ] }) export class AppRoutingModule {}A matriz
routes: Routes = [];define as rotas ou os caminhos de navegação para mapeamentos de componentes do Angular.AemPageMatcheré um roteador Angular personalizado UrlMatcher, que corresponde a qualquer item que "se pareça" com uma página no AEM que faz parte deste aplicativo Angular.PageComponenté o componente de Angular que representa uma Página no AEM e é usado para renderizar as rotas correspondentes. OPageComponenté revisado posteriormente no tutorial.AemPageDataResolver, fornecido pelo AEM SPA Editor JS SDK, é um Resolvedor de Roteador Angular personalizado usado para transformar a URL de rota, que é o caminho no AEM, incluindo a extensão .html, para o caminho de recurso no AEM, que é o caminho da página menos a extensão.Por exemplo, o
AemPageDataResolvertransforma a URL de uma rota decontent/wknd-spa-angular/us/en/home.htmlem um caminho de/content/wknd-spa-angular/us/en/home. Isso é usado para resolver o conteúdo da página com base no caminho na API do modelo JSON.AemPageRouteReuseStrategy, fornecido pelo AEM SPA Editor JS SDK, é uma RouteReuseStrategy personalizada que impede a reutilização dePageComponententre rotas. Caso contrário, o conteúdo da página "A" poderá ser exibido ao navegar para a página "B". -
Abra o arquivo
page.component.tsemui.frontend/src/app/components/page/.code language-js ... export class PageComponent { items; itemsOrder; path; constructor( private route: ActivatedRoute, private modelManagerService: ModelManagerService ) { this.modelManagerService .getData({ path: this.route.snapshot.data.path }) .then(data => { this.path = data[Constants.PATH_PROP]; this.items = data[Constants.ITEMS_PROP]; this.itemsOrder = data[Constants.ITEMS_ORDER_PROP]; }); } }O
PageComponenté necessário para processar o JSON recuperado do AEM e é usado como o componente do Angular para renderizar as rotas.ActivatedRoute, que é fornecido pelo módulo Angular Router, contém o estado indicando qual conteúdo JSON da Página do AEM deve ser carregado nesta instância do componente Angular Page.ModelManagerService, obtém os dados JSON com base na rota e mapeia os dados para as variáveis de classepath,items,itemsOrder. Eles serão passados para o AEMPageComponent -
Abrir o arquivo
page.component.htmlemui.frontend/src/app/components/page/code language-html <aem-page class="structure-page" [attr.data-cq-page-path]="path" [cqPath]="path" [cqItems]="items" [cqItemsOrder]="itemsOrder"> </aem-page>aem-pageinclui o AEMPageComponent. As variáveispath,itemseitemsOrdersão passadas paraAEMPageComponent. OAemPageComponent, fornecido pelo JavaScript SDK do Editor de SPA, iterará sobre esses dados e instanciará dinamicamente os componentes do Angular com base nos dados JSON, conforme visto no tutorial de Componentes do Map.O
PageComponenté na verdade apenas um proxy para oAEMPageComponente é oAEMPageComponentque faz a maioria do trabalho pesado para mapear corretamente o modelo JSON para os componentes do Angular.
Inspecione o roteamento de SPA no AEM
-
Abra um terminal e pare o servidor de desenvolvimento do webpack, se iniciado. Navegue até a raiz do projeto e implante o projeto no AEM usando suas habilidades em Maven:
code language-shell $ cd aem-guides-wknd-spa $ mvn clean install -PautoInstallSinglePackagenote caution CAUTION O projeto Angular tem algumas regras de lista muito rigorosas ativadas. Se a compilação Maven falhar, verifique o erro e procure erros Lint encontrados nos arquivos listados.. Corrija todos os problemas encontrados pelo linter e execute novamente o comando Maven. -
Navegue até a página inicial do SPA no AEM: http://localhost:4502/content/wknd-spa-angular/us/en/home.html e abra as ferramentas de desenvolvedor do seu navegador. As capturas de tela abaixo são feitas no navegador Google Chrome.
Atualize a página e você verá uma solicitação XHR para
/content/wknd-spa-angular/us/en.model.json, que é a Raiz SPA. Observe que apenas três páginas secundárias são incluídas com base na configuração de profundidade da hierarquia para o modelo Raiz de SPA definido anteriormente no tutorial. Isso não inclui a Página 3.
-
Com as ferramentas do desenvolvedor abertas, navegue até a Página 3:
Observe que uma nova solicitação XHR é feita para:
/content/wknd-spa-angular/us/en/home/page-2/page-3.model.json
O Gerenciador de Modelos do AEM entende que o conteúdo JSON da Página 3 não está disponível e aciona automaticamente a solicitação XHR adicional.
-
Continue navegando no SPA usando os vários links de navegação. Observe que nenhuma solicitação XHR adicional é feita e que nenhuma atualização de página completa ocorre. Isso torna o SPA rápido para o usuário final e reduz as solicitações desnecessárias de volta para o AEM.
-
Experimente os deep links navegando diretamente para: http://localhost:4502/content/wknd-spa-angular/us/en/home/page-2.html. Observe que o botão Voltar do navegador continua funcionando.
Parabéns! congratulations
Parabéns, você aprendeu como várias exibições no SPA podem ser compatíveis, mapeando para Páginas do AEM com o SPA Editor SDK. A navegação dinâmica foi implementada com o roteamento Angular e adicionada ao componente Header.
Você sempre pode exibir o código concluído em GitHub ou verificar o código localmente alternando para a ramificação Angular/navigation-routing-solution.
Próximas etapas next-steps
Criar um componente personalizado - Saiba como criar um componente personalizado a ser usado com o Editor de SPA do AEM. Saiba como desenvolver caixas de diálogo de criação e Modelos Sling para estender o modelo JSON e preencher um componente personalizado.