Adicionar navegação e roteamento navigation-routing
Saiba como várias exibições no SPA são compatíveis usando páginas AEM e o SDK Editor de SPA. A navegação dinâmica é implementada usando rotas de Angular e adicionada a um componente de Cabeçalho existente.
Objetivo
- Entenda as opções de roteamento do modelo SPA disponíveis ao usar o Editor SPA.
- Saiba como usar o roteamento de Angulars para navegar entre diferentes exibições do SPA.
- Implemente uma navegação dinâmica orientada pela hierarquia de página 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 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 de AEM local usando Maven:
code language-shell $ mvn clean install -PautoInstallSinglePackage
Se 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 WKND. O pacote pode ser instalado usando o Gerenciador de Pacotes do 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
.
Atualizações do Inspect HeaderComponent inspect-header
Nos capítulos anteriores, o componente HeaderComponent
foi adicionado como um componente de Angular puro 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
de dentro do AEM.
-
No IDE de sua escolha, abra o projeto inicial do SPA para este capítulo.
-
Abaixo do módulo
ui.frontend
, inspecione o arquivoheader.component.ts
em:ui.frontend/src/app/components/header/header.component.ts
.Várias atualizações foram feitas, incluindo a adição de um
HeaderEditConfig
e umMapTo
para 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
.items
conterá uma matriz de objetos de navegação transmitidos do AEM. -
No módulo
ui.apps
, inspecione a definição do componente AEMHeader
: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 AEM
Header
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 SPA:
Em Componentes Permitidos > Geral > selecione o componente Contêiner de Layout.
Em Componentes Permitidos > ANGULAR SPA WKND - ESTRUTURA > selecione o componente Cabeçalho:
Em Componentes Permitidos > ANGULAR WKND SPA - 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 SPA WKND".
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
Header
preenchido como parte do modelo:
Criar páginas secundárias
Em seguida, crie páginas adicionais no AEM que servirão como as diferentes visualizações no SPA. Também vamos inspecionar 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 Angular do WKND SPA e clique em Criar > Página:
-
Em Modelo, selecione Página SPA. Em Propriedades, digite "Página 1" para o Título e "página-1" como o nome.
Clique em Criar e, na janela pop-up da caixa de diálogo, clique em Abrir para abrir a página no Editor de SPA 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
:children
você 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, já que 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 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 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-3
do modelo JSON inicial.Posteriormente, observaremos como o SDK do editor SPA 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 AEM
Header
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 AEM é modelada no JSON que pode ser usado para preencher um menu de navegação. Lembre-se de que o componente
Header
herda toda a funcionalidade do Componente principal de Navegação e o conteúdo exposto por meio do JSON é mapeado automaticamente para a anotação do Angular@Input
. -
Abra uma nova janela de terminal e navegue até a pasta
ui.frontend
do projeto SPA. Crie um novoNavigationComponent
usando 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
NavigationLink
usando a CLI do Angular no diretóriocomponents/navigation
recé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.ts
em/src/app/components/navigation/navigation-link.ts
. -
Popular
navigation-link.ts
com 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
data
seja o objeto JSON transmitido pelo AEM. Essa classe é usada emNavigationComponent
eHeaderComponent
para 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 objetosNavigationLink
para 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 data
segue 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() {} }
NavigationComponent
espera umobject[]
chamadoitems
que seja o modelo JSON do AEM. Esta classe expõe um único métodoget navigationLinks()
que retorna uma matriz deNavigationLink
objetos. -
Abra o arquivo
navigation.component.html
e 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 chamadorecursiveListTmpl
e passar onavigationLinks
como uma variável chamadalinks
.Adicionar o
recursiveListTmpl
em 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 tipoNavigationLink
e todos os métodos/propriedades criados por essa classe estão disponíveis.[routerLink]
é usado em vez do atributohref
normal. 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 olink
atual tiver uma matrizchildren
não vazia. -
Atualize
navigation.component.spec.ts
para adicionar suporte aRouterTestingModule
:code language-diff ... + import { RouterTestingModule } from '@angular/router/testing'; ... beforeEach(async(() => { TestBed.configureTestingModule({ + imports: [ RouterTestingModule ], declarations: [ NavigationComponent ] }) .compileComponents(); })); ...
É necessário adicionar
RouterTestingModule
porque o componente usa[routerLink]
. -
Atualize
navigation.component.scss
para 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.frontend
no projeto 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 anteriormente no tutorial.Atualmente, o
HeaderComponent
já 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.ts
emui.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.path
retorna o caminho da rota de Angular atual. 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.html
e substitua o espaço reservado estático para a navegação por uma referência aoNavigationComponent
recé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]=items
passa o@Input() items
deHeaderComponent
paraNavigationComponent
, onde ele compilará a navegação. -
Abra
header.component.spec.ts
e 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
NavigationComponent
agora é 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 ser capaz de navegar para diferentes visualizaçõ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.ts
emui.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 de Angular.AemPageMatcher
é um roteador de Angular personalizado UrlMatcher, que corresponde a qualquer item que "se pareça" com uma página no AEM que faz parte deste aplicativo de 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 SDK JS do Editor SPA AEM, é um Resolvedor de Roteador de Angular AEM AEM personalizado usado para transformar a URL da rota, que é o caminho no, incluindo a extensão .html, para o caminho do recurso no, que é o caminho da página menos a extensão.Por exemplo, o
AemPageDataResolver
transforma a URL de uma rota decontent/wknd-spa-angular/us/en/home.html
em 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 SDK JS do Editor SPA AEM, é uma RouteReuseStrategy personalizada que impede a reutilização dePageComponent
entre 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.ts
emui.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 que indica qual conteúdo JSON da Página AEM deve ser carregado nesta instância do componente Página de Angular.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.html
emui.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-page
inclui o AEMPageComponent. As variáveispath
,items
eitemsOrder
são passadas paraAEMPageComponent
. OAemPageComponent
, fornecido por meio do SDK JavaScript 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 mapa.O
PageComponent
é na verdade apenas um proxy para oAEMPageComponent
e é oAEMPageComponent
que faz a maioria do trabalho pesado para mapear corretamente o modelo JSON para os componentes do Angular.
Inspect: o roteamento do 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 -PautoInstallSinglePackage
note 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 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 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 agiliza o SPA para o usuário final e reduz solicitações desnecessárias de volta ao 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 suportadas pelo mapeamento para páginas AEM com o SDK do Editor do SPA. A navegação dinâmica foi implementada com o roteamento de Angulars 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
AEM Criar um componente personalizado - Saiba como criar um componente personalizado a ser usado com o Editor de SPA. Saiba como desenvolver caixas de diálogo de criação e Modelos Sling para estender o modelo JSON e preencher um componente personalizado.