Desenvolvimento com o Editor SPA do AEM - Tutorial do mundo Hello

AVISO

Este tutorial é obsoleto. É recomendável seguir um destes procedimentos: Introdução ao Editor SPA do AEM e Angular ou Introdução ao Editor SPA do AEM e React

O Editor de SPA do AEM fornece suporte para edição no contexto de um Aplicativo de página única ou SPA. Este tutorial é uma introdução ao desenvolvimento de SPA para ser usado com o SDK JS do Editor SPA do AEM. O tutorial estenderá o aplicativo do We.Retail Journal adicionando um componente personalizado Hello World. Os usuários podem concluir o tutorial usando estruturas React ou Angular.

OBSERVAÇÃO

O recurso Editor de aplicativo de página única (SPA) requer o service pack 2 do AEM 6.4 ou mais recente.

O Editor de SPA é a solução recomendada para projetos que exigem renderização do lado do cliente com base na estrutura do SPA (por exemplo, Reagir ou Angular).

Leitura de pré-requisito

Este tutorial destina-se a destacar as etapas necessárias para mapear um componente SPA a um componente AEM para ativar a edição no contexto. Os usuários que iniciam este tutorial devem conhecer os conceitos básicos de desenvolvimento com o Adobe Experience Manager, o AEM, bem como o desenvolvimento com o React of Angular Framework. O tutorial aborda tarefas de desenvolvimento de back-end e de front-end.

Recomenda-se que os seguintes recursos sejam revisados antes de iniciar este tutorial:

Ambiente de desenvolvimento local

Este tutorial foi projetado para:

Adobe Experience Manager 6.5 ou Adobe Experience Manager 6.4 + Service Pack 5

Neste tutorial, as seguintes tecnologias e ferramentas devem ser instaladas:

  1. Java 11
  2. Apache Maven - 3.3.1+
  3. Node.js - 8.11.1+ e npm 5.6.0+ (npm é instalado com node.js)

Verifique novamente a instalação das ferramentas acima, abrindo um novo terminal e executando o seguinte:

$ java -version
java version "11 +"

$ mvn -version
Apache Maven 3.3.9

$ node --version
v8.11.1

$ npm --version
6.1.0

Visão geral

O conceito básico é mapear um Componente SPA para um Componente AEM. Componentes do AEM, executando o lado do servidor, exportam conteúdo no formato JSON. O conteúdo JSON é consumido pelo SPA, executando o lado do cliente no navegador. Um mapeamento 1:1 entre componentes do SPA e um componente do AEM é criado.

Mapeamento de componentes SPA

Estruturas populares React JS e Angular são suportadas imediatamente. Os usuários podem concluir este tutorial em Angular ou Reagir, qualquer estrutura com a qual estejam mais confortáveis.

Configuração do projeto

O desenvolvimento de SPA tem um pé no desenvolvimento do AEM e o outro fora. O objetivo é permitir que o desenvolvimento de SPA ocorra independentemente e (principalmente) seja independente do AEM.

  • Os projetos de SPA podem operar independentemente do projeto AEM durante o desenvolvimento front-end.
  • As ferramentas e tecnologias de build front-end como Webpack, NPM, Grunt e Gulpcontinuam a ser usadas.
  • Para criar o para o AEM, o projeto do SPA é compilado e incluído automaticamente no projeto do AEM.
  • Pacotes AEM padrão usados para implantar o SPA no AEM.

Visão geral de artefatos e implantação

O desenvolvimento de SPA tem um pé no desenvolvimento do AEM e o outro fora - permitindo que o desenvolvimento de SPA ocorra independentemente e (principalmente) seja agnóstico ao AEM.

O objetivo deste tutorial é estender o aplicativo de diário We.Retail com um novo componente. Comece baixando o código-fonte do aplicativo We.Retail Journal e implantando em um AEM local.

  1. ​Baixe o código do diário We.Retail mais recente em GitHub.

    Ou clone o repositório da linha de comando:

    $ git clone git@github.com:adobe/aem-sample-we-retail-journal.git
    
    OBSERVAÇÃO

    O tutorial funcionará em relação à ramificação master com a versão 1.2.1-SNAPSHOT do projeto.

  2. A seguinte estrutura deve ser visível:

    Estrutura da pasta do projeto

    O projeto contém os seguintes módulos maven:

    • all: Incorpora e instala o projeto inteiro em um único pacote.
    • bundles: Contém dois pacotes OSGi: commons e core que contêm Sling Models e outro código Java.
    • ui.apps: contém as partes /apps do projeto, ou seja, clientlibs JS & CSS, componentes, configurações específicas do modo de execução.
    • ui.content: contém conteúdo estrutural e configurações (/content, /conf)
    • react-app: Aplicativo We.Retail Journal React. Este é um módulo Maven e um projeto do webpack.
    • angular-app: Aplicativo Angular do diário We.Retail. Este é um módulo Maven e um projeto do webpack.
  3. Abra uma nova janela de terminal e execute o seguinte comando para criar e implantar o aplicativo inteiro em uma instância do AEM local em execução em http://localhost:4502.

    $ cd <src>/aem-sample-we-retail-journal
    $ mvn -PautoInstallSinglePackage clean install
    
    OBSERVAÇÃO

    Neste projeto, o perfil Maven para criar e empacotar o projeto inteiro é autoInstallSinglePackage

  4. Vá até:

    O aplicativo de diário We.Retail deve ser exibido no editor do AEM Sites.

  5. No modo Editar, selecione um componente a ser editado e faça uma atualização do conteúdo.

    Editar um componente

  6. Selecione o ícone Propriedades da página para abrir as Propriedades da página. Selecione Editar Modelo para abrir o modelo da página.

    Menu de propriedades da página

  7. Na versão mais recente do Editor do SPA, Modelos editáveis podem ser usados da mesma forma que com implementações de Sites tradicionais. Isso será revisitado posteriormente com nosso componente personalizado.

    OBSERVAÇÃO

    Somente o AEM 6.5 e o AEM 6.4 + Service Pack 5 oferecem suporte a Modelos editáveis.

Visão geral do desenvolvimento

Desenvolvimento de visão geral

As iterações de desenvolvimento de SPA ocorrem independentemente do AEM. Quando o SPA está pronto para ser implantado no AEM, as seguintes etapas de alto nível ocorrem (como ilustrado acima).

  1. A build do projeto AEM é chamada, o que, por sua vez, aciona uma build do projeto SPA. O diário We.Retail usa o frontend-maven-plugin.
  2. O aem-clientlib-generator do projeto SPA incorpora o SPA compilado como uma Biblioteca de clientes do AEM no projeto do AEM.
  3. O projeto do AEM gera um pacote do AEM, incluindo o SPA compilado, além de qualquer outro código do AEM de suporte.

Criar componente do AEM

Persona: Desenvolvedor do AEM

Um componente do AEM será criado primeiro. O componente AEM é responsável pela renderização das propriedades JSON que são lidas pelo componente React . O componente do AEM também é responsável por fornecer uma caixa de diálogo para quaisquer propriedades editáveis do componente.

Usando Eclipse ou outro IDE, importe o projeto We.Retail Journal Maven.

  1. Atualize o reator pom.xml para remover o plug-in Apache Rat. Este plug-in verifica cada arquivo para garantir que haja um cabeçalho de licença. Para nossos propósitos, não precisamos nos preocupar com essa funcionalidade.

    Em aem-sample-we-retail-journal/pom.xml remova apache-rate-plugin:

    <!-- Remove apache-rat-plugin -->
    <plugin>
            <groupId>org.apache.rat</groupId>
            <artifactId>apache-rat-plugin</artifactId>
            <configuration>
                <excludes combine.children="append">
                    <exclude>*</exclude>
                        ...
                </excludes>
            </configuration>
            <executions>
                    <execution>
                        <phase>verify</phase>
                        <goals>
                            <goal>check</goal>
                        </goals>
                </execution>
            </executions>
        </plugin>
    
  2. No módulo we-retail-journal-content (<src>/aem-sample-we-retail-journal/ui.apps) crie um novo nó sob ui.apps/jcr_root/apps/we-retail-journal/components chamado helloworld do tipo cq:Component.

  3. Adicione as seguintes propriedades ao componente helloworld, representado em XML (/helloworld/.content.xml) abaixo:

    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
        jcr:description="Hello World Component for We.Retail Journal"
        jcr:primaryType="cq:Component"
        jcr:title="Hello World"
        componentGroup="We.Retail Journal" />
    

    Componente Hello World

    OBSERVAÇÃO

    Para ilustrar o recurso Modelos editáveis, definimos propositalmente o componentGroup="Custom Components". Em um projeto do mundo real, é melhor minimizar o número de grupos de componentes, de modo que um grupo melhor seria “We.Retail Journal” para corresponder aos outros componentes de conteúdo.

    Somente o AEM 6.5 e o AEM 6.4 + Service Pack 5 oferecem suporte a modelos editáveis.

  4. Em seguida, uma caixa de diálogo será criada para permitir que uma mensagem personalizada seja configurada para o componente Hello World. Abaixo de /apps/we-retail-journal/components/helloworld adicione um nome de nó cq:dialog de nt:unstructured.

  5. O cq:dialog exibirá um único campo de texto que persiste texto em uma propriedade chamada message. Abaixo do recém-criado cq:dialog adicione os seguintes nós e propriedades, representados em XML abaixo (helloworld/_cq_dialog/.content.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" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
        jcr:primaryType="nt:unstructured"
        jcr:title="We.Retail Journal - Hello World"
        sling:resourceType="cq/gui/components/authoring/dialog">
        <content
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/coral/foundation/container">
            <items jcr:primaryType="nt:unstructured">
                <tabs
                    jcr:primaryType="nt:unstructured"
                    sling:resourceType="granite/ui/components/coral/foundation/tabs"
                    maximized="{Boolean}true">
                    <items jcr:primaryType="nt:unstructured">
                        <properties
                            jcr:primaryType="nt:unstructured"
                            jcr:title="Properties"
                            sling:resourceType="granite/ui/components/coral/foundation/container"
                            margin="{Boolean}true">
                            <items jcr:primaryType="nt:unstructured">
                                <columns
                                    jcr:primaryType="nt:unstructured"
                                    sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
                                    margin="{Boolean}true">
                                    <items jcr:primaryType="nt:unstructured">
                                        <column
                                            jcr:primaryType="nt:unstructured"
                                            sling:resourceType="granite/ui/components/coral/foundation/container">
                                            <items jcr:primaryType="nt:unstructured">
                                                <message
                                                    jcr:primaryType="nt:unstructured"
                                                    sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                    fieldLabel="Message"
                                                    name="./message"
                                                    required="{Boolean}true"/>
                                            </items>
                                        </column>
                                    </items>
                                </columns>
                            </items>
                        </properties>
                    </items>
                </tabs>
            </items>
        </content>
    </jcr:root>
    

    estrutura de arquivos

    A definição de nó XML acima criará uma caixa de diálogo com um único campo de texto que permitirá que um usuário insira uma “mensagem”. Observe a propriedade name="./message" no nó <message />. Esse é o nome da propriedade que será armazenada no JCR no AEM.

  6. Em seguida, uma caixa de diálogo de política vazia será criada (cq:design_dialog). A caixa de diálogo Política é necessária para ver o componente no Editor de modelo. Para esse caso de uso simples, uma caixa de diálogo ficará vazia.

    Abaixo de /apps/we-retail-journal/components/helloworld adicione um nome de nó cq:design_dialog de nt:unstructured.

    A configuração é representada no XML abaixo (helloworld/_cq_design_dialog/.content.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" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
    jcr:primaryType="nt:unstructured" />
    
  7. Implante a base de código no AEM a partir da linha de comando:

    $ cd <src>/aem-sample-we-retail-journal/content
    $ mvn -PautoInstallPackage clean install
    

    Em CRXDE Lite, valide se o componente foi implantado inspecionando a pasta em /apps/we-retail-journal/components:

    Estrutura de componentes implantada no CRXDE Lite

Criar Modelo Sling

Persona: Desenvolvedor do AEM

Em seguida, um Sling Model é criado para retornar o componente Hello World. Em um caso de uso tradicional do WCM, o Sling Model implementa qualquer lógica comercial e um script de renderização do lado do servidor (HTL) fará uma chamada para o Sling Model. Isso mantém o script de renderização relativamente simples.

Sling Models também são usadas no caso de uso de SPA para implementar a lógica de negócios do lado do servidor. A diferença é que no caso de uso SPA, o Sling Models expõe seus métodos como JSON serializado.

OBSERVAÇÃO

Como prática recomendada, os desenvolvedores devem procurar usar os Componentes principais do AEM quando possível. Entre outros recursos, os Componentes principais fornecem Sling Models com saída JSON "pronta para SPA", permitindo que os desenvolvedores se concentrem mais na apresentação de front-end.

  1. No editor de sua escolha, abra o projeto we-retail-journal-commons ( <src>/aem-sample-we-retail-journal/bundles/commons).

  2. No pacote com.adobe.cq.sample.spa.commons.impl.models:

    • Crie uma nova classe chamada HelloWorld.
    • Adicionar uma interface de implementação para com.adobe.cq.export.json.ComponentExporter.

    Assistente de Nova Classe Java

    A interface ComponentExporter deve ser implementada para que Sling Model seja compatível com os Serviços de conteúdo do AEM.

     package com.adobe.cq.sample.spa.commons.impl.models;
    
     import com.adobe.cq.export.json.ComponentExporter;
    
     public class HelloWorld implements ComponentExporter {
    
         @Override
         public String getExportedType() {
             return null;
         }
     }
    
  3. Adicione uma variável estática chamada RESOURCE_TYPE para identificar o tipo de recurso do componente HelloWorld:

     ...
     public class HelloWorld implements ComponentExporter {
    
         static final String RESOURCE_TYPE = "we-retail-journal/components/helloworld";
    
         ...
     }
    
  4. Adicione as anotações OSGi para @Model e @Exporter. A anotação @Model registrará a classe como Sling Model. A anotação @Exporter exporá os métodos como JSON serializado usando a estrutura Jackson Exporter.

    import org.apache.sling.api.SlingHttpServletRequest;
    import org.apache.sling.models.annotations.Exporter;
    import org.apache.sling.models.annotations.Model;
    import com.adobe.cq.export.json.ExporterConstants;
    ...
    
    @Model(
            adaptables = SlingHttpServletRequest.class,
            adapters = {ComponentExporter.class},
            resourceType = HelloWorld.RESOURCE_TYPE
    )
    @Exporter(
            name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, 
            extensions = ExporterConstants.SLING_MODEL_EXTENSION
    )
    public class HelloWorld implements ComponentExporter {
    
    ...
    
  5. Implemente o método getDisplayMessage() para retornar a propriedade JCR message. Use a anotação Sling Model de @ValueMapValue para facilitar a recuperação da propriedade message armazenada abaixo do componente. A anotação @Optional é importante, pois quando o componente é adicionado pela primeira vez à página, message não será preenchido.

    Como parte da lógica de negócios, uma string, "Hello", será anexada à mensagem.

    import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
    import org.apache.sling.models.annotations.Optional;
    
    ...
    
    public class HelloWorld implements ComponentExporter {
    
       static final String RESOURCE_TYPE = "we-retail-journal/components/helloworld";
    
       private static final String PREPEND_MSG = "Hello";
    
        @ValueMapValue @Optional
        private String message;
    
        public String getDisplayMessage() {
            if(message != null && message.length() > 0) {
                return PREPEND_MSG + " "  + message;
            }
            return null;
        }
    
    ...
    
    OBSERVAÇÃO

    O nome do método getDisplayMessage é importante. Quando o Sling Model for serializado com o Jackson Exporter, ele será exposto como uma propriedade JSON: displayMessage. O Jackson Exporter serializará e exporá todos os métodos getter que não utilizam um parâmetro (a menos que estejam marcados explicitamente para ignorar). Posteriormente, no aplicativo React/Angular, leremos o valor dessa propriedade e o exibiremos como parte do aplicativo.

    O método getExportedType também é importante. O valor do componente resourceType será usado para "mapear" os dados JSON para o componente front-end (Angular / Reagir). Vamos explorar isso na próxima seção.

  6. Implemente o método getExportedType() para retornar o tipo de recurso do componente HelloWorld.

     @Override
        public String getExportedType() {
            return RESOURCE_TYPE;
        }
    

    O código completo para HelloWorld.java pode ser encontrado aqui.

  7. Implante o código no AEM usando o Apache Maven:

    $ cd <src>/sample-we-retail-spa-content/bundles/commons
    $ mvn -PautoInstallPackage clean install
    

    Verifique a implantação e o registro do Sling Model navegando até Status > Sling Models no console OSGi.

    Você deve ver que o HelloWorld Modelo do Sling está vinculado ao we-retail-journal/components/helloworld tipo de recurso do Sling e está registrado como Sling Model Exporter Servlet:

    com.adobe.cq.sample.spa.commons.impl.models.HelloWorld - we-retail-journal/components/helloworld
    com.adobe.cq.sample.spa.commons.impl.models.HelloWorld exports 'we-retail-journal/components/helloworld' with selector 'model' and extension '[Ljava.lang.String;@6480f3e5' with exporter 'jackson'
    

Criar componente de reação

Persona: Desenvolvedor front-end

Em seguida, o componente React será criado. Abra o módulo response-app ( <src>/aem-sample-we-retail-journal/react-app) usando o editor de sua escolha.

OBSERVAÇÃO

Ignore esta seção se você estiver interessado apenas em Angular development.

  1. Dentro da pasta react-app, navegue até a pasta src. Expanda a pasta de componentes para exibir os arquivos de componentes React existentes.

    reagir à estrutura do arquivo de componentes

  2. Adicione um novo arquivo abaixo da pasta de componentes chamada HelloWorld.js.

  3. Abrir HelloWorld.js. Adicione uma declaração de importação para importar a biblioteca do componente React . Adicione uma segunda declaração de importação para importar o auxiliar MapTo fornecido pela Adobe. A ajuda MapTo fornece um mapeamento do componente React para o JSON do componente AEM.

    import React, {Component} from 'react';
    import {MapTo} from '@adobe/cq-react-editable-components';
    
  4. Abaixo das importações, crie uma nova classe chamada HelloWorld que estende a interface React Component. Adicione o método render() necessário à classe HelloWorld.

    import React, {Component} from 'react';
    import {MapTo} from '@adobe/cq-react-editable-components';
    
    class HelloWorld extends Component {
    
        render() {
    
        }
    }
    
  5. A ajuda MapTo inclui automaticamente um objeto chamado cqModel como parte das props do componente React. O cqModel inclui todas as propriedades expostas pelo Sling Model.

    Lembre-se de que o Sling Model criado anteriormente contém um método getDisplayMessage(). getDisplayMessage() é traduzido como uma chave JSON chamada displayMessage when output.

    Implemente o método render() para gerar uma tag h1 que contenha o valor de displayMessage. JSX, uma extensão de sintaxe para JavaScript, é usada para retornar a marcação final do componente.

    ...
    
    class HelloWorld extends Component {
        render() {
    
            if(this.props.displayMessage) {
                return (
                    <div className="cmp-helloworld">
                        <h1 className="cmp-helloworld_message">{this.props.displayMessage}</h1>
                    </div>
                );
            }
            return null;
        }
    }
    
  6. Implemente um método de configuração de edição. Esse método é passado por meio da ajuda MapTo e fornece ao editor do AEM informações para exibir um espaço reservado, caso o componente esteja vazio. Isso ocorre quando o componente é adicionado ao SPA, mas ainda não foi criado. Adicione o seguinte abaixo da classe HelloWorld:

    ...
    
    class HelloWorld extends Component {
        ...
    }
    
    const HelloWorldEditConfig = {
    
        emptyLabel: 'Hello World',
    
        isEmpty: function(props) {
            return !props || !props.displayMessage || props.displayMessage.trim().length < 1;
        }
    };
    
    ...
    
  7. No final do arquivo, chame o auxiliar MapTo, transmitindo a classe HelloWorld e HelloWorldEditConfig. Isso mapeará o Componente de reação para o componente AEM com base no tipo de recurso do Componente AEM: we-retail-journal/components/helloworld.

    MapTo('we-retail-journal/components/helloworld')(HelloWorld, HelloWorldEditConfig);
    

    O código concluído para HelloWorld.js pode ser encontrado aqui.

  8. Abra o arquivo ImportComponents.js. Ele pode ser encontrado em <src>/aem-sample-we-retail-journal/react-app/src/ImportComponents.js.

    Adicione uma linha para exigir o HelloWorld.js com os outros componentes no pacote JavaScript compilado:

    ...
      require('./components/Text');
      require('./components/Image');
      require('./components/HelloWorld');
    ...
    
  9. Na pasta components crie um novo arquivo chamado HelloWorld.css como um irmão de HelloWorld.js. Preencha o arquivo com o seguinte para criar um estilo básico para o componente HelloWorld:

    /* HelloWorld.css to style HelloWorld component */
    
    .cmp-helloworld_message {
        text-align: center;
        color: #ff505e;
        text-transform: unset;
        letter-spacing: unset;
    }
    
  10. Abra novamente HelloWorld.js e atualize abaixo das instruções de importação para exigir HelloWorld.css:

    import React, {Component} from 'react';
    import {MapTo} from '@adobe/cq-react-editable-components';
    
    require('./HelloWorld.css');
    
    ...
    
  11. Implante o código no AEM usando o Apache Maven:

    $ cd <src>/sample-we-retail-spa-content
    $ mvn -PautoInstallSinglePackage clean install
    
  12. Em CRXDE-Lite abra /apps/we-retail-journal/react/clientlibs/we-retail-journal-react/js/app.js. Execute uma pesquisa rápida para HelloWorld em app.js para verificar se o componente React foi incluído no aplicativo compilado.

    OBSERVAÇÃO

    app. jis é o aplicativo React fornecido. O código não é mais legível por humanos. O comando npm run build acionou uma build otimizada que gera JavaScript compilado que pode ser interpretado pelos navegadores modernos.

Criar componente angular

Persona: Desenvolvedor front-end

OBSERVAÇÃO

Ignore esta seção se você estiver interessado apenas no desenvolvimento do React.

Em seguida, o componente Angular será criado. Abra o módulo angular-app (<src>/aem-sample-we-retail-journal/angular-app) usando o editor de sua escolha.

  1. Dentro da pasta angular-app, navegue até a pasta src correspondente. Expanda a pasta de componentes para exibir os arquivos de componentes Angular existentes.

    Estrutura de arquivo angular

  2. Adicione uma nova pasta abaixo da pasta de componentes chamada helloworld. Abaixo da pasta helloworld adicione novos arquivos chamados helloworld.component.css, helloworld.component.html, helloworld.component.ts.

    /angular-app
        /src
            /app
                /components
    +                /helloworld
    +                    helloworld.component.css
    +                    helloworld.component.html
    +                    helloworld.component.ts
    
  3. Abrir helloworld.component.ts. Adicione uma declaração de importação para importar as classes Angular Component e Input. Crie um novo componente, apontando styleUrls e templateUrl para helloworld.component.css e helloworld.component.html. Por fim, exporte a classe HelloWorldComponent com a entrada esperada de displayMessage.

    //helloworld.component.ts
    
    import { Component, Input } from '@angular/core';
    
    @Component({
      selector: 'app-helloworld',
      host: { 'class': 'cmp-helloworld' },
      styleUrls:['./helloworld.component.css'],
      templateUrl: './helloworld.component.html',
    })
    
    export class HelloWorldComponent {
      @Input() displayMessage: string;
    }
    
    OBSERVAÇÃO

    Se você lembrar o Sling Model criado anteriormente, havia um método getDisplayMessage(). O JSON serializado deste método será displayMessage, que agora estamos lendo no aplicativo Angular.

  4. Abra helloworld.component.html para incluir uma tag h1 que imprimirá a propriedade displayMessage:

    <h1 *ngIf="displayMessage" class="cmp-helloworld_message">
        {{displayMessage}}
    </h1>
    
  5. Atualize helloworld.component.css para incluir alguns estilos básicos do componente.

    :host-context {
        display: block;
    };
    
    .cmp-helloworld {
        display:block;
    }
    .cmp-helloworld_message {
        text-align: center;
        color: #ff505e;
        text-transform: unset;
        letter-spacing: unset;
    }
    
  6. Atualize helloworld.component.spec.ts com a seguinte base de teste:

    import { async, ComponentFixture, TestBed } from '@angular/core/testing';
    
    import { HelloWorldComponent } from './helloworld.component';
    
        describe('HelloWorld', () => {
        let component: HelloWorldComponent;
        let fixture: ComponentFixture<HelloWorldComponent>;
    
        beforeEach(async(() => {
            TestBed.configureTestingModule({
            declarations: [ HelloWorldComponent ]
            })
            .compileComponents();
        }));
    
        beforeEach(() => {
            fixture = TestBed.createComponent(HelloWorldComponent);
            component = fixture.componentInstance;
            fixture.detectChanges();
        });
    
        it('should create', () => {
            expect(component).toBeTruthy();
        });
    });
    
  7. Próxima atualização src/components/mapping.ts para incluir o HelloWorldComponent. Adicione um HelloWorldEditConfig que marcará o espaço reservado no editor do AEM antes que o componente seja configurado. Por fim, adicione uma linha para mapear o componente AEM para o componente Angular com o auxiliar MapTo.

    // src/components/mapping.ts
    
    import { HelloWorldComponent } from "./helloworld/helloworld.component";
    
    ...
    
    const HelloWorldEditConfig = {
    
        emptyLabel: 'Hello World',
    
        isEmpty: function(props) {
            return !props || !props.displayMessage || props.displayMessage.trim().length < 1;
        }
    };
    
    ...
    
    MapTo('we-retail-journal/components/helloworld')(HelloWorldComponent, HelloWorldEditConfig);
    

    O código completo para mapping.ts pode ser encontrado aqui.

  8. Atualize src/app.module.ts para atualizar o NgModule. Adicione o HelloWorldComponent como uma declaração que pertence ao AppModule. Adicione também o HelloWorldComponent como um entryComponent para que ele seja compilado e incluído dinamicamente no aplicativo conforme o modelo JSON é processado.

    import { HelloWorldComponent } from './components/helloworld/helloworld.component';
    
    ...
    
    @NgModule({
      imports: [BrowserModule.withServerTransition({ appId: 'we-retail-sample-angular' }),
        SpaAngularEditableComponentsModule,
      AngularWeatherWidgetModule.forRoot({
        key: "37375c33ca925949d7ba331e52da661a",
        name: WeatherApiName.OPEN_WEATHER_MAP,
        baseUrl: 'http://api.openweathermap.org/data/2.5'
      }),
        AppRoutingModule,
        BrowserTransferStateModule],
      providers: [ModelManagerService,
        { provide: APP_BASE_HREF, useValue: '/' }],
      declarations: [AppComponent,
        TextComponent,
        ImageComponent,
        WeatherComponent,
        NavigationComponent,
        MenuComponent,
        MainContentComponent,
        HelloWorldComponent],
      entryComponents: [TextComponent,
        ImageComponent,
        WeatherComponent,
        NavigationComponent,
        MainContentComponent,
        HelloWorldComponent],
      bootstrap: [AppComponent]
     })
    

    O código concluído para app.module.ts pode ser encontrado aqui.

  9. Implante o código no AEM usando o Maven:

    $ cd <src>/sample-we-retail-spa-content
    $ mvn -PautoInstallSinglePackage clean install
    
  10. Em CRXDE-Lite abra /apps/we-retail-journal/angular/clientlibs/we-retail-journal-angular/js/main.js. Execute uma pesquisa rápida para HelloWorld em main.js para verificar se o componente Angular foi incluído.

    OBSERVAÇÃO

    main. jis é o aplicativo Angular fornecido. O código não é mais legível por humanos. O comando npm run build acionou uma build otimizada que gera JavaScript compilado que pode ser interpretado pelos navegadores modernos.

Atualização do modelo

  1. Navegue até o Modelo editável para as versões React e/ou Angular:

  2. Selecione o Contêiner de layout principal e selecione o ícone Política para abrir sua política:

    Selecionar política de layout

    Em Propriedades > Componentes permitidos, faça uma pesquisa por Custom Components. Você deve ver o componente Hello World, selecione-o. Salve as alterações clicando na caixa de seleção no canto superior direito.

    Configuração da política do contêiner de layout

  3. Depois de salvar, você deve ver o componente HelloWorld como um componente permitido no Contêiner de layout.

    Componentes permitidos atualizados

    OBSERVAÇÃO

    Somente o AEM 6.5 e o AEM 6.4.5 oferecem suporte ao recurso Modelo editável do Editor do SPA. Se estiver usando o AEM 6.4, será necessário configurar manualmente a política para Componentes permitidos por meio do CRXDE Lite: /conf/we-retail-journal/react/settings/wcm/policies/wcm/foundation/components/responsivegrid/default ou /conf/we-retail-journal/angular/settings/wcm/policies/wcm/foundation/components/responsivegrid/default

    CRXDE Lite mostrando as configurações de política atualizadas para Componentes permitidos no Contêiner de layout:

    CRXDE Lite mostrando as configurações de política atualizadas para Componentes permitidos no Contêiner de layout

Colocando tudo junto

  1. Navegue até as páginas Angular ou Reagir:

  2. Encontre o componente Hello World e arraste e solte o componente Hello World na página.

    hello world arrastar e soltar

    O espaço reservado deve aparecer.

    Olá, empresário mundial

  3. Selecione o componente e adicione uma mensagem na caixa de diálogo, ou seja, "Mundo" ou "Seu nome". Salve as alterações.

    componente renderizado

    Observe que a string "Hello" sempre está anexada à mensagem. Isso é resultado da lógica no HelloWorld.java Sling Model.

Próximas etapas

Solução concluída para o componente HelloWorld

Resolução de problemas

Não é possível criar o projeto no Eclipse

Erro: um erro ao importar o We.Retail Journal projeto para o Eclipse para execuções de meta não reconhecidas:

Execution npm install, Execution npm run build, Execution default-analyze-classes*

assistente de erro de eclipse

Resolução: Clique em Finish para resolvê-los mais tarde. Isso não deve impedir a conclusão do tutorial.

Erro: O módulo React react-app, não é criado com êxito durante uma build Maven.

Solução: Tente excluir a node_modules pasta abaixo do aplicativo de reação. Execute novamente o comando Apache Maven mvn clean install -PautoInstallSinglePackage a partir da raiz do projeto.

Dependências não satisfeitas no AEM

Erro de dependência do gerenciador de pacotes

Se uma dependência do AEM não for atendida, no AEM Package Manager ou no AEM Web Console (Felix Console), isso indica que o recurso do Editor do SPA não está disponível.

O componente não é exibido

Erro: Mesmo depois de uma implantação bem-sucedida e verificar se as versões compiladas dos aplicativos React/Angular têm o helloworld componente atualizado, meu componente não é exibido quando eu o arrasto na página. Posso ver o componente na interface do usuário do AEM.

Resolução: Limpe o histórico/cache do seu navegador e/ou abra um novo navegador ou use o modo incógnito. Se isso não funcionar, invalide o cache da biblioteca do cliente na instância do AEM local. O AEM tenta armazenar bibliotecas de clientes grandes em cache para ser eficiente. Às vezes, a invalidação manual do cache é necessária para corrigir problemas em que o código desatualizado é armazenado em cache.

Navegue até: http://localhost:4502/libs/granite/ui/content/dumplibs.rebuild.html e clique em Invalidar cache. Retorne à página Reagir/Angular e atualize a página.

Recriar biblioteca do cliente

Nesta página

Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now