Sviluppo con AEM SPA Editor - Esercitazione a livello mondiale

AVVERTENZA

L’Editor SPA di AEM supporta la modifica contestuale di un’applicazione a pagina singola o SPA. Questa esercitazione è un’introduzione allo sviluppo di applicazioni a pagina singola da utilizzare con l’SDK JS per l’editor di applicazioni a pagina singola di AEM. L’esercitazione estenderà l’app We.Retail Journal aggiungendo un componente personalizzato Hello World . Gli utenti possono completare l’esercitazione utilizzando i framework React o Angular.

NOTA

La funzione Editor applicazioni a pagina singola (SPA) richiede il service pack 2 o successivo di AEM 6.4.

L’Editor SPA è la soluzione consigliata per i progetti che richiedono il rendering lato client basato su framework SPA (ad esempio React o Angular).

Lettura obbligatoria

Questa esercitazione ha lo scopo di evidenziare i passaggi necessari per mappare un componente SPA su un componente AEM per abilitare la modifica nel contesto. Gli utenti che iniziano questa esercitazione devono avere familiarità con i concetti di base dello sviluppo con Adobe Experience Manager, AEM e devono sviluppare con React dei framework Angular. L’esercitazione tratta sia le attività di sviluppo back-end che quelle front-end.

Prima di avviare questa esercitazione, è consigliabile consultare le risorse seguenti:

Ambiente di sviluppo locale

Questa esercitazione è progettata per:

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

In questa esercitazione devono essere installate le seguenti tecnologie e strumenti:

  1. Java 11
  2. Apache Maven - 3.3.1+
  3. Node.js - 8.11.1+ e npm 5.6.0+ (npm è installato con node.js)

Controllare l'installazione degli strumenti di cui sopra aprendo un nuovo terminale ed eseguendo quanto segue:

$ java -version
java version "11 +"

$ mvn -version
Apache Maven 3.3.9

$ node --version
v8.11.1

$ npm --version
6.1.0

Panoramica

Il concetto di base è quello di mappare un componente SPA su un componente AEM. I componenti AEM, che eseguono lato server, esportano il contenuto sotto forma di JSON. Il contenuto JSON viene utilizzato dall’applicazione a pagina singola, che esegue lato client nel browser. Viene creata una mappatura 1:1 tra i componenti SPA e un componente AEM.

Mappatura del componente SPA

I framework popolari React JS e Angular sono supportati come predefiniti. Gli utenti possono completare questa esercitazione in Angular o React, a prescindere dal framework utilizzato.

Configurazione del progetto

Lo sviluppo di applicazioni a pagina singola ha un piede nello sviluppo di AEM e l’altro. L’obiettivo è quello di consentire lo sviluppo di applicazioni a pagina singola in modo indipendente e (per lo più) agnostico per AEM.

  • I progetti SPA possono funzionare indipendentemente dal progetto AEM durante lo sviluppo front-end.
  • Continuano ad essere utilizzati strumenti e tecnologie di compilazione front-end come Webpack, NPM, Grunt e Gulp.
  • Per creare per AEM, il progetto SPA viene compilato e incluso automaticamente nel progetto AEM.
  • Pacchetti AEM standard utilizzati per distribuire l’applicazione a pagina singola in AEM.

Panoramica degli artefatti e della distribuzione

Lo sviluppo di applicazioni a pagina singola ha un piede nello sviluppo di AEM e l’altro fuori - consentendo lo sviluppo di applicazioni a pagina singola in modo indipendente e (per lo più) agnostico per AEM.

L’obiettivo di questa esercitazione è quello di estendere l’app We.Retail Journal con un nuovo componente. Per iniziare, scarica il codice sorgente per l’app We.Retail Journal e distribuisci in un AEM locale.

  1. ​Scarica il codice Journal We.Retail più recente da GitHub.

    Oppure duplica l’archivio dalla riga di comando:

    $ git clone git@github.com:adobe/aem-sample-we-retail-journal.git
    
    NOTA

    L’esercitazione funzionerà sul ramo master con la versione 1.2.1-SNAPSHOT del progetto.

  2. La seguente struttura deve essere visibile:

    Struttura della cartella di progetto

    Il progetto contiene i seguenti moduli Maven:

    • all: Incorpora e installa l’intero progetto in un unico pacchetto.
    • bundles: Contiene due bundle OSGi: beni comuni e core che contengono Sling Models e altro codice Java.
    • ui.apps: contiene le parti /apps del progetto, ad esempio clientlibs JS e CSS, componenti, configurazioni specifiche della modalità runmode.
    • ui.content: contiene contenuti e configurazioni strutturali (/content, /conf)
    • react-app: Applicazione React Journal We.Retail Questo è sia un modulo Maven che un progetto webpack.
    • angular-app: Applicazione Angular We.Retail Journal Si tratta sia di un modulo Maven che di un progetto webpack.
  3. Apri una nuova finestra terminale ed esegui il seguente comando per creare e distribuire l'intera app in un'istanza AEM locale in esecuzione su http://localhost:4502.

    $ cd <src>/aem-sample-we-retail-journal
    $ mvn -PautoInstallSinglePackage clean install
    
    NOTA

    In questo progetto il profilo Maven da generare e creare il pacchetto dell’intero progetto è autoInstallSinglePackage

  4. Accedi a:

    L’app We.Retail Journal deve essere visualizzata nell’editor di AEM Sites.

  5. In modalità Modifica, seleziona un componente da modificare ed effettua un aggiornamento al contenuto.

    Modificare un componente

  6. Seleziona l’icona Proprietà pagina per aprire Proprietà pagina. Seleziona Modifica modello per aprire il modello della pagina.

    Menu delle proprietà della pagina

  7. Nell’ultima versione dell’Editor SPA, è possibile utilizzare Modelli modificabili nello stesso modo delle implementazioni tradizionali di Sites. Questo verrà rivisto in seguito con il nostro componente personalizzato.

    NOTA

    Solo AEM 6.5 e AEM 6.4 + Service Pack 5 supportano i modelli modificabili.

Panoramica sullo sviluppo

Panoramica dello sviluppo

Le iterazioni di sviluppo per applicazioni a pagina singola si verificano indipendentemente da AEM. Quando l’applicazione a pagina singola è pronta per essere implementata in AEM, si verificano i seguenti passaggi di alto livello (come illustrato in precedenza).

  1. Viene richiamata la build del progetto AEM, che a sua volta attiva una build del progetto SPA. Il giornale di registrazione We.Retail utilizza il tag frontend-maven-plugin.
  2. Il progetto SPA aem-clientlib-generator incorpora l’applicazione a pagina singola compilata come libreria client AEM nel progetto AEM.
  3. Il progetto AEM genera un pacchetto AEM, inclusa la SPA compilata, più qualsiasi altro codice AEM supportato.

Crea componente AEM

Persona: Sviluppatore AEM

Per prima cosa verrà creato un componente AEM. Il componente AEM è responsabile del rendering delle proprietà JSON lette dal componente React. Il componente AEM fornisce anche una finestra di dialogo per tutte le proprietà modificabili del componente.

Utilizzando Eclipse o un altro IDE, importa il progetto Maven di We.Retail Journal.

  1. Aggiorna il reattore pom.xml per rimuovere il plugin Apache Rat. Questo plug-in controlla ogni file per assicurarsi che sia presente un’intestazione di Licenza. Per i nostri scopi non dobbiamo preoccuparci di questa funzionalità.

    In aem-sample-we-retail-journal/pom.xml rimuovere 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. Nel modulo we-retail-journal-content (<src>/aem-sample-we-retail-journal/ui.apps) crea un nuovo nodo sotto ui.apps/jcr_root/apps/we-retail-journal/components denominato helloworld di tipo cq:Component.

  3. Aggiungi le seguenti proprietà al componente helloworld, rappresentato in XML (/helloworld/.content.xml) di seguito:

    <?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"

    NOTA

    Per illustrare la funzione Modelli modificabili, abbiamo impostato appositamente componentGroup="Custom Components". In un progetto reale, è meglio ridurre al minimo il numero di gruppi di componenti, quindi un gruppo migliore sarebbe “We.Retail Journal” per corrispondere agli altri componenti di contenuto.

    Solo AEM 6.5 e AEM 6.4 + Service Pack 5 supportano i modelli modificabili.

  4. Verrà quindi creata una finestra di dialogo per consentire la configurazione di un messaggio personalizzato per il componente Hello World . Sotto /apps/we-retail-journal/components/helloworld aggiungi un nome di nodo cq:dialog di nt:unstructured.

  5. Il cq:dialog visualizzerà un singolo campo di testo che persiste del testo a una proprietà denominata message. Sotto la nuova creazione cq:dialog aggiungi i seguenti nodi e proprietà, rappresentati in XML di seguito (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>
    

    struttura del file

    La definizione del nodo XML di cui sopra crea una finestra di dialogo con un singolo campo di testo che consente all’utente di inserire un “messaggio”. Prendi nota della proprietà name="./message" all’interno del nodo <message /> . Questo è il nome della proprietà che verrà memorizzata nel JCR in AEM.

  6. Quindi verrà creata una finestra di dialogo dei criteri vuota (cq:design_dialog). La finestra di dialogo Criterio è necessaria per visualizzare il componente nell’Editor modelli. Per questo semplice caso d’uso sarà una finestra di dialogo vuota.

    Sotto /apps/we-retail-journal/components/helloworld aggiungi un nome di nodo cq:design_dialog di nt:unstructured.

    La configurazione è rappresentata nel codice XML seguente (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. Distribuisci la base di codice in AEM dalla riga di comando:

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

    In CRXDE Lite convalida che il componente sia stato distribuito ispezionando la cartella in /apps/we-retail-journal/components:

    Struttura dei componenti distribuiti in CRXDE Lite

Crea modello Sling

Persona: Sviluppatore AEM

Successivamente viene creato un Sling Model per eseguire il backup del componente Hello World. In un caso d’uso WCM tradizionale, Sling Model implementa qualsiasi logica di business e uno script di rendering lato server (HTL) effettuerà una chiamata a Sling Model. Questo mantiene lo script di rendering relativamente semplice.

Sling Models sono utilizzati anche nel caso di utilizzo per applicazioni a pagina singola per implementare la logica di business lato server. La differenza è che nel caso di utilizzo SPA, il Sling Models espone i suoi metodi come JSON serializzato.

NOTA

Come best practice, gli sviluppatori devono cercare di utilizzare componenti core di AEM quando possibile. Tra le altre funzionalità, i componenti core forniscono Sling Models un output JSON "pronto per l’applicazione a pagina singola", che consente agli sviluppatori di concentrarsi maggiormente sulla presentazione front-end.

  1. Nell’editor desiderato, apri il progetto we-retail-journal-commons ( <src>/aem-sample-we-retail-journal/bundles/commons).

  2. Nel pacchetto com.adobe.cq.sample.spa.commons.impl.models:

    • Crea una nuova classe denominata HelloWorld.
    • Aggiungi un'interfaccia di implementazione per com.adobe.cq.export.json.ComponentExporter.

    Creazione guidata nuova classe Java

    Affinché Sling Model sia compatibile con AEM Content Services, è necessario implementare l’interfaccia ComponentExporter .

     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. Aggiungi una variabile statica denominata RESOURCE_TYPE per identificare il tipo di risorsa del componente HelloWorld:

     ...
     public class HelloWorld implements ComponentExporter {
    
         static final String RESOURCE_TYPE = "we-retail-journal/components/helloworld";
    
         ...
     }
    
  4. Aggiungi le annotazioni OSGi per @Model e @Exporter. L’annotazione @Model registra la classe come Sling Model. L’annotazione @Exporter espone i metodi come JSON serializzato utilizzando il framework 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. Implementa il metodo getDisplayMessage() per restituire la proprietà JCR message. Utilizza l’ Sling Model annotazione di @ValueMapValue per semplificare il recupero della proprietà message memorizzata sotto il componente. L’annotazione @Optional è importante in quanto quando il componente viene aggiunto per la prima volta alla pagina, message non verrà compilata.

    Come parte della logica di business, al messaggio verrà anteposta una stringa, "Hello".

    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;
        }
    
    ...
    
    NOTA

    Il nome del metodo getDisplayMessage è importante. Quando il Sling Model viene serializzato con Jackson Exporter, verrà esposto come proprietà JSON: displayMessage. I metodi Jackson Exporter serializzano ed espongono tutti i metodi getter che non accettano un parametro (a meno che non siano contrassegnati in modo esplicito per l'ignorare). Successivamente nell'app React / Angular leggeremo questo valore della proprietà e lo mostreremo come parte dell'applicazione.

    Anche il metodo getExportedType è importante. Il valore del componente resourceType verrà utilizzato per "mappare" i dati JSON sul componente front-end (Angular / React). Lo esploreremo nella prossima sezione.

  6. Implementa il metodo getExportedType() per restituire il tipo di risorsa del componente HelloWorld.

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

    Il codice completo per HelloWorld.java è disponibile qui.

  7. Distribuisci il codice in AEM utilizzando Apache Maven:

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

    Verifica la distribuzione e la registrazione di Sling Model passando a Stato > Modelli Sling nella console OSGi.

    Dovresti vedere che il modello HelloWorld Sling è associato al tipo di risorsa we-retail-journal/components/helloworld Sling e che è registrato come 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'
    

Crea componente React

Persona: Sviluppatore front-end

Quindi, verrà creato il componente React. Apri il modulo react-app ( <src>/aem-sample-we-retail-journal/react-app) utilizzando l'editor desiderato.

NOTA

Puoi saltare questa sezione se sei interessato solo a Sviluppo angolare.

  1. All’interno della cartella react-app individua la relativa cartella src. Espandi la cartella dei componenti per visualizzare i file dei componenti React esistenti.

    struttura del file react component

  2. Aggiungi un nuovo file sotto la cartella dei componenti denominato HelloWorld.js.

  3. Apri HelloWorld.js. Aggiungi un’istruzione di importazione per importare la libreria dei componenti React. Aggiungi una seconda istruzione di importazione per importare l’ MapTo helper fornito da Adobe. L’ MapTo helper fornisce una mappatura del componente React sul JSON del componente AEM.

    import React, {Component} from 'react';
    import {MapTo} from '@adobe/cq-react-editable-components';
    
  4. Sotto le importazioni crea una nuova classe denominata HelloWorld che estende l’interfaccia React Component. Aggiungi il metodo render() richiesto alla classe HelloWorld .

    import React, {Component} from 'react';
    import {MapTo} from '@adobe/cq-react-editable-components';
    
    class HelloWorld extends Component {
    
        render() {
    
        }
    }
    
  5. L’ MapTo helper include automaticamente un oggetto denominato cqModel come parte delle proprietà del componente React. Il cqModel include tutte le proprietà esposte dal Sling Model.

    Ricorda che il Sling Model creato in precedenza contiene un metodo getDisplayMessage(). getDisplayMessage() viene tradotto come chiave JSON denominata displayMessage durante l’output.

    Implementa il metodo render() per restituire un tag h1 contenente il valore di displayMessage. JSX, un'estensione di sintassi a JavaScript, viene utilizzato per restituire il markup finale del 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. Implementa un metodo di configurazione di modifica. Questo metodo viene trasmesso tramite l’ MapTo helper e fornisce all’editor AEM informazioni per visualizzare un segnaposto nel caso in cui il componente sia vuoto. Questo si verifica quando il componente viene aggiunto all’applicazione a pagina singola ma non è ancora stato creato. Aggiungi quanto segue sotto la classe HelloWorld :

    ...
    
    class HelloWorld extends Component {
        ...
    }
    
    const HelloWorldEditConfig = {
    
        emptyLabel: 'Hello World',
    
        isEmpty: function(props) {
            return !props || !props.displayMessage || props.displayMessage.trim().length < 1;
        }
    };
    
    ...
    
  7. Alla fine del file, chiama l’ MapTo helper, passando la classe HelloWorld e la classe HelloWorldEditConfig. Viene eseguito il mapping del componente React al componente AEM in base al tipo di risorsa del componente AEM: we-retail-journal/components/helloworld.

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

    Il codice completato per HelloWorld.js si trova qui.

  8. Aprire il file ImportComponents.js. È disponibile all'indirizzo <src>/aem-sample-we-retail-journal/react-app/src/ImportComponents.js.

    Aggiungi una riga per richiedere il HelloWorld.js con gli altri componenti nel bundle JavaScript compilato:

    ...
      require('./components/Text');
      require('./components/Image');
      require('./components/HelloWorld');
    ...
    
  9. Nella cartella components crea un nuovo file denominato HelloWorld.css come pari di HelloWorld.js. Per creare uno stile di base per il componente HelloWorld , compila il file con i seguenti elementi:

    /* HelloWorld.css to style HelloWorld component */
    
    .cmp-helloworld_message {
        text-align: center;
        color: #ff505e;
        text-transform: unset;
        letter-spacing: unset;
    }
    
  10. Riapri HelloWorld.js e aggiorna le istruzioni di importazione per richiedere HelloWorld.css:

    import React, {Component} from 'react';
    import {MapTo} from '@adobe/cq-react-editable-components';
    
    require('./HelloWorld.css');
    
    ...
    
  11. Distribuisci il codice in AEM utilizzando Apache Maven:

    $ cd <src>/sample-we-retail-spa-content
    $ mvn -PautoInstallSinglePackage clean install
    
  12. In CRXDE-Lite apri /apps/we-retail-journal/react/clientlibs/we-retail-journal-react/js/app.js. Esegui una ricerca rapida per HelloWorld in app.js per verificare che il componente React sia stato incluso nell’app compilata.

    NOTA

    app. jsis l'app React inclusa nel pacchetto. Il codice non è più leggibile dall'uomo. Il comando npm run build ha attivato una build ottimizzata per l'output di JavaScript compilato che può essere interpretato dai browser moderni.

Crea componente angolare

Persona: Sviluppatore front-end

NOTA

Puoi saltare questa sezione se sei interessato solo allo sviluppo React.

Quindi, verrà creato il componente Angular. Apri il modulo angular-app (<src>/aem-sample-we-retail-journal/angular-app) utilizzando l'editor desiderato.

  1. All’interno della cartella angular-app , passa alla relativa cartella src . Espandi la cartella dei componenti per visualizzare i file dei componenti Angular esistenti.

    Struttura del file angolare

  2. Aggiungi una nuova cartella sotto la cartella dei componenti denominata helloworld. Sotto la cartella helloworld aggiungi nuovi file denominati 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. Apri helloworld.component.ts. Aggiungi un’istruzione import per importare le classi Angular Component e Input . Crea un nuovo componente, indicando i valori styleUrls e templateUrl in helloworld.component.css e helloworld.component.html. Infine, esporta la classe HelloWorldComponent con l'input previsto di 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;
    }
    
    NOTA

    Se si ricorda il Sling Model creato in precedenza, era presente un metodo getDisplayMessage(). Il JSON serializzato di questo metodo sarà displayMessage, che stiamo leggendo nell'app Angular.

  4. Apri helloworld.component.html per includere un tag h1 che stamperà la proprietà displayMessage :

    <h1 *ngIf="displayMessage" class="cmp-helloworld_message">
        {{displayMessage}}
    </h1>
    
  5. Aggiorna helloworld.component.css per includere alcuni stili di base per il componente.

    :host-context {
        display: block;
    };
    
    .cmp-helloworld {
        display:block;
    }
    .cmp-helloworld_message {
        text-align: center;
        color: #ff505e;
        text-transform: unset;
        letter-spacing: unset;
    }
    
  6. Aggiornare helloworld.component.spec.ts con il seguente banco di prova:

    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. Aggiornamento successivo src/components/mapping.ts per includere il HelloWorldComponent. Aggiungi un HelloWorldEditConfig che contrassegna il segnaposto nell’editor AEM prima che il componente sia stato configurato. Infine, aggiungi una riga per mappare il componente AEM al componente Angular con l’ MapTo helper .

    // 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);
    

    Il codice completo per mapping.ts si trova qui.

  8. Aggiorna src/app.module.ts per aggiornare NgModule. Aggiungi il HelloWorldComponent come dichiarazione che appartiene al AppModule. Aggiungi anche il HelloWorldComponent come entryComponent in modo che venga compilato e incluso dinamicamente nell'app mentre il modello JSON viene elaborato.

    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]
     })
    

    Il codice completato per app.module.ts si trova qui.

  9. Distribuisci il codice in AEM utilizzando Maven:

    $ cd <src>/sample-we-retail-spa-content
    $ mvn -PautoInstallSinglePackage clean install
    
  10. In CRXDE-Lite apri /apps/we-retail-journal/angular/clientlibs/we-retail-journal-angular/js/main.js. Esegui una ricerca rapida per HelloWorld in main.js per verificare che il componente Angular sia stato incluso.

    NOTA

    main. jsis l'app Angular in bundle. Il codice non è più leggibile dall'uomo. Il comando npm run build ha attivato una build ottimizzata che restituisce JavaScript compilato che può essere interpretato dai browser moderni.

Aggiornamento del modello

  1. Passa al Modello modificabile per le versioni React e/o Angular:

  2. Seleziona il Contenitore di layout principale e fai clic sull'icona Criterio per aprire il relativo criterio:

    Selezionare il criterio di layout

    In Proprietà > Componenti consentiti, esegui una ricerca per Custom Components. Dovresti visualizzare il componente Hello World , selezionalo. Salva le modifiche facendo clic sulla casella di controllo nell’angolo in alto a destra.

    Configurazione dei criteri dei contenitori di layout

  3. Dopo il salvataggio, il componente HelloWorld dovrebbe essere visualizzato come componente consentito nel Contenitore di layout.

    Componenti consentiti aggiornati

    NOTA

    Solo AEM 6.5 e AEM 6.4.5 supportano la funzione Modello modificabile dell’Editor SPA. Se utilizzi AEM 6.4, dovrai configurare manualmente i criteri per i componenti consentiti tramite CRXDE Lite: /conf/we-retail-journal/react/settings/wcm/policies/wcm/foundation/components/responsivegrid/default o /conf/we-retail-journal/angular/settings/wcm/policies/wcm/foundation/components/responsivegrid/default

    CRXDE Lite che mostra le configurazioni dei criteri aggiornate per Componenti consentiti nel Contenitore di layout:

    CRXDE Lite che mostra le configurazioni dei criteri aggiornate per i componenti consentiti nel contenitore di layout

Mettere tutto insieme

  1. Passa alle pagine Angular o React :

  2. Trova il componente Hello World e trascina e rilascia il componente Hello World sulla pagina.

    hello world drag + drop

    Viene visualizzato il segnaposto.

    Ciao a tutti il titolare del posto

  3. Seleziona il componente e aggiungi un messaggio nella finestra di dialogo, ad esempio "World" o "Your Name". Salva le modifiche.

    componente di rendering

    La stringa "Ciao" è sempre preceduta dal messaggio. Questo è il risultato della logica in HelloWorld.java Sling Model.

Passaggi successivi

Soluzione completata per il componente HelloWorld

Risoluzione dei problemi

Impossibile generare il progetto in Eclipse

Errore: errore durante l’importazione del We.Retail Journal progetto in Eclipse per esecuzioni di obiettivi non riconosciute:

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

procedura guidata di errore eclipse

Risoluzione: Fare clic su Fine per risolvere i problemi in un secondo momento. Questo non dovrebbe impedire il completamento dell'esercitazione.

Errore: Il modulo React, react-app, non viene generato correttamente durante una build Maven.

Risoluzione: Prova a eliminare la node_modules cartella sotto la react-app. Esegui nuovamente il comando Apache Maven mvn clean install -PautoInstallSinglePackage dalla directory principale del progetto.

Dipendenze non soddisfatte in AEM

Errore di dipendenza di Gestione pacchetti

Se una dipendenza AEM non è soddisfatta, in Gestione pacchetti AEM o in Console web AEM (Console Felix), ciò indica che la funzione Editor SPA non è disponibile.

Il componente non viene visualizzato

Errore: Anche dopo una distribuzione di successo e dopo aver verificato che le versioni compilate delle app React/Angular abbiano il helloworld componente aggiornato, il mio componente non viene visualizzato quando lo trascino sulla pagina. Il componente è visibile nell’interfaccia utente di AEM.

Risoluzione: Cancella la cronologia/cache del browser e/o apri un nuovo browser o utilizza la modalità in incognito. Se questo non funziona, invalida la cache della libreria client sull'istanza AEM locale. AEM tenta di memorizzare nella cache librerie client di grandi dimensioni per essere efficiente. A volte è necessario annullare manualmente la validità della cache per risolvere i problemi in cui il codice obsoleto viene memorizzato nella cache.

Passa a: http://localhost:4502/libs/granite/ui/content/dumplibs.rebuild.html e fai clic su Annulla validità cache. Torna alla pagina React/Angular e aggiorna la pagina.

Rigenera libreria client

In questa pagina