Introdução ao SPA no AEM - Angular getting-started-with-spas-in-aem-angular
Aplicativos de página única (SPAs) podem oferecer experiências interessantes para usuários de sites. Os desenvolvedores desejam criar sites usando estruturas SPA, e os autores desejam editar o conteúdo no AEM para um site criado usando estruturas SPA.
O recurso de criação do SPA oferece uma solução abrangente para oferecer suporte ao SPA no AEM. Este artigo apresenta um aplicativo simplificado de SPA na estrutura do Angular e explica como ele é montado, permitindo que você comece a usar seu próprio SPA rapidamente.
Introdução introduction
Este artigo resume o funcionamento básico de um SPA simples e o mínimo que você precisa saber para que o seu funcione.
Para obter mais detalhes sobre como o SPA funciona no AEM, consulte os seguintes documentos:
Este documento abordará a estrutura de um SPA simplificado e ilustrará como ele funciona para que você possa aplicar essa compreensão ao seu próprio SPA.
Dependências, configuração e criação dependencies-configuration-and-building
Além da dependência de Angular esperada, a amostra SPA pode usar bibliotecas adicionais para tornar a criação do SPA mais eficiente.
Dependências dependencies
O arquivo package.json
define os requisitos do pacote SPA geral. As dependências mínimas necessárias do AEM estão listadas aqui.
"dependencies": {
"@adobe/aem-angular-editable-components": "~1.0.3",
"@adobe/aem-spa-component-mapping": "~1.0.5",
"@adobe/aem-spa-page-model-manager": "~1.0.3"
}
O aem-clientlib-generator
é usado para tornar a criação de bibliotecas de clientes automática como parte do processo de compilação.
"aem-clientlib-generator": "^1.4.1",
Mais detalhes sobre o aem-clientlib-generator estão disponíveis no GitHub.
aem-clientlib-generator
necessária é a 1.4.1.O aem-clientlib-generator
está configurado no arquivo clientlib.config.js
da seguinte maneira.
module.exports = {
// default working directory (can be changed per 'cwd' in every asset option)
context: __dirname,
// path to the clientlib root folder (output)
clientLibRoot: "./../content/jcr_root/apps/my-angular-app/clientlibs",
libs: {
name: "my-angular-app",
allowProxy: true,
categories: ["my-angular-app"],
embed: ["my-angular-app.responsivegrid"],
jsProcessor: ["min:gcc"],
serializationFormat: "xml",
assets: {
js: [
"dist/**/*.js"
],
css: [
"dist/**/*.css"
]
}
}
};
Compilação building
Na verdade, a compilação do aplicativo usa o Webpack para transpilação, além do aem-clientlib-generator para a criação automática da biblioteca do cliente. Portanto, o comando build será semelhante a:
"build": "ng build --build-optimizer=false && clientlib",
Depois de criado, o pacote pode ser carregado para uma instância AEM.
Arquétipo de projeto do AEM aem-project-archetype
Qualquer projeto do AEM deve utilizar o Arquétipo de projeto do AEM, que aceita projetos SPA que usam o React ou o Angular e utiliza o SDK de SPA.
Estrutura do aplicativo application-structure
Incluir as dependências e criar seu aplicativo conforme descrito anteriormente deixará você com um pacote de SPA que funciona e que você pode carregar para sua instância do AEM.
A próxima seção deste documento abordará como um SPA no AEM está estruturado, os arquivos importantes que orientam o aplicativo e como eles funcionam juntos.
Um componente de imagem simplificado é usado como exemplo, mas todos os componentes do aplicativo se baseiam no mesmo conceito.
app.module.ts app-module-ts
O ponto de entrada no SPA é o arquivo app.module.ts
mostrado aqui simplificado para se concentrar no conteúdo importante.
// app.module.ts
import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { SpaAngularEditableComponentsModule } from '@adobe/aem-angular-editable-components';
import { AppRoutingModule } from './app-routing.module';
@NgModule({
imports: [ BrowserModule.withServerTransition({ appId: 'my-angular-app' }),
SpaAngularEditableComponentsModule,
AppRoutingModule,
BrowserTransferStateModule ],
providers: ...,
declarations: [ ... ],
entryComponents: [ ... ],
bootstrap: [ AppComponent ]
})
export class AppModule {}
O arquivo app.module.ts
é o ponto inicial do aplicativo e contém a configuração inicial do projeto e usa AppComponent
para inicializar o aplicativo.
Instanciação estática static-instantiation
Quando o componente é instanciado estaticamente usando o template do componente, o valor deve ser passado do modelo para as propriedades do componente. Os valores do modelo são passados como atributos para ficarem disponíveis posteriormente como propriedades de componente.
app.component.ts app-component-ts
Uma vez que o app.module.ts
inicializa o AppComponent
, ele pode inicializar o aplicativo, que é mostrado aqui em uma versão simplificada para se concentrar no conteúdo importante.
// app.component.ts
import { Component } from '@angular/core';
import { ModelManager } from '@adobe/aem-spa-page-model-manager';
import { Constants } from "@adobe/aem-angular-editable-components";
@Component({
selector: 'app-root',
template: `
<router-outlet></router-outlet>
`
})
export class AppComponent {
items;
itemsOrder;
path;
constructor() {
ModelManager.initialize().then(this.updateData.bind(this));
}
private updateData(model) {
this.path = model[Constants.PATH_PROP];
this.items = model[Constants.ITEMS_PROP];
this.itemsOrder = model[Constants.ITEMS_ORDER_PROP];
}
}
main-content.component.ts main-content-component-ts
Ao processar a página, app.component.ts
chama main-content.component.ts
listado aqui em uma versão simplificada.
import { Component } from '@angular/core';
import { ModelManagerService } from '../model-manager.service';
import { ActivatedRoute } from '@angular/router';
import { Constants } from "@adobe/aem-angular-editable-components";
@Component({
selector: 'app-main',
template: `
<aem-page class="structure-page" [attr.data-cq-page-path]="path" [cqPath]="path" [cqItems]="items" [cqItemsOrder]="itemsOrder" ></aem-page>
`
})
export class MainContentComponent {
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 MainComponent
assimila a representação JSON do modelo de página e processa o conteúdo para envolver/decorar cada elemento da página. Mais detalhes sobre o Page
podem ser encontrados no documento Blueprint do SPA.
image.component.ts image-component-ts
O Page
é composto de componentes. Com o JSON assimilado, o Page
pode processar esses componentes, como o image.component.ts
, como mostrado aqui.
/// image.component.ts
import { Component, Input } from '@angular/core';
const ImageEditConfig = {
emptyLabel: 'Image',
isEmpty: function(cqModel) {
return !cqModel || !cqModel.src || cqModel.src.trim().length < 1;
}
};
@Component({
selector: 'app-image',
templateUrl: './image.component.html',
})
export class ImageComponent {
@Input() src: string;
@Input() alt: string;
@Input() title: string;
}
MapTo('my-angular-app/components/image')(ImageComponent, ImageEditConfig);
A ideia central do AEM é a ideia de mapear componentes do SPA AEM para componentes do SPA e atualizar o componente quando o conteúdo é modificado (e vice-versa). Consulte o documento Visão geral do editor de SPA para obter um resumo desse modelo de comunicação.
MapTo('my-angular-app/components/image')(Image, ImageEditConfig);
O método MapTo
mapeia o componente SPA para o componente AEM. Ele suporta o uso de uma única string ou uma matriz de strings.
ImageEditConfig
é um objeto de configuração que contribui para habilitar os recursos de criação de um componente, fornecendo os metadados necessários para que o editor gere espaços reservados
Se não houver conteúdo, os rótulos serão fornecidos como espaços reservados para representar o conteúdo vazio.
Propriedades passadas dinamicamente dynamically-passed-properties
Os dados provenientes do modelo são transmitidos dinamicamente como propriedades do componente.
image.component.html image-component-html
Finalmente, a imagem pode ser renderizada em image.component.html
.
// image.component.html
<img [src]="src" [alt]="alt" [title]="title"/>
Compartilhamento de informações entre componentes do SPA sharing-information-between-spa-components
É regularmente necessário que os componentes de um aplicativo de página única compartilhem informações. Há várias maneiras recomendadas de fazer isso, listadas a seguir em uma ordem crescente de complexidade.
- Opção 1: Centralize a lógica e a difusão nos componentes necessários, por exemplo, usando uma classe util como uma solução puramente orientada a objetos.
- Opção 2: Compartilhe estados do componente usando uma biblioteca de estado como NgRx.
- Opção 3: Aproveite a hierarquia de objetos personalizando e estendendo o componente de contêiner.
Próximas etapas next-steps
Para obter um guia passo a passo sobre como criar seu próprio SPA AEM, consulte o Introdução ao SPA Editor - Tutorial de eventos WKND.
Para obter mais informações sobre como se organizar para desenvolver AEM para SPA, consulte o artigo Desenvolvendo SPA para AEM.
SPA Para obter mais detalhes sobre o modelo dinâmico para o mapeamento de componentes e como ele funciona no AEM, consulte o artigo Modelo dinâmico para mapeamento de componentes para SPA.
Se você quiser implementar o SPA no AEM para uma estrutura diferente do React ou do Angular SPA AEM SPA ou simplesmente quiser se aprofundar em como funciona o SDK do para o, consulte o artigo Blueprint.