Show Menu
ARGOMENTI×

L'anatomia di un'app

Adobe consiglia di utilizzare SPA Editor per i progetti che richiedono il rendering lato client basato sul framework dell'applicazione a pagina singola (ad es. React). Per saperne di più .

Modelli di pagina per app mobili

I componenti di pagina creati per l’app si basano sul componente /libs/mobileapps/components/angular/ng-page ( aperto in CRXDE Lite su un server locale). Questo componente contiene i seguenti script JSP che il componente eredita o sostituisce:
  • ng-page.jsp
  • head.jsp
  • body.jsp
  • angular-app-module.js.jsp
  • angular-route-fragment.js.jsp
  • angular-app-controllers.js.jsp
  • controller.js.jsp
  • template.jsp
  • angular-module-list.js.jsp
  • header.jsp
  • footer.jsp
  • js_clientlibs.jsp
  • css_clientlibs.jsp

ng-page.jsp

Determina il nome dell'applicazione utilizzando la applicationName proprietà ed espone l'applicazione tramite pageContext.
Include head.jsp e body.jsp.

head.jsp

Inserisce l' <head> elemento della pagina dell'app.
Se desiderate ignorare la proprietà meta viewport dell'app, questo è il file che avete ignorato.
Seguendo le procedure ottimali, l'app include la parte css delle librerie client nella sezione head, mentre JS è incluso nell'elemento < body> di chiusura.

body.jsp

Il corpo di una pagina Angular viene rappresentato in modo diverso a seconda che wcmMode venga rilevato (!= WCMMode.DISABLED) per determinare se la pagina viene aperta per la creazione o come pagina pubblicata.
Modalità autore
In modalità di creazione, ogni singola pagina viene rappresentata separatamente. Angular non gestisce il routing tra le pagine, né un ng-view utilizzato per caricare un modello parziale che contiene i componenti della pagina. Al contrario, il contenuto del modello di pagina (template.jsp) viene incluso sul lato server tramite il cq:include tag .
Questa strategia consente alle funzioni di authoring (come l’aggiunta e la modifica di componenti nel sistema paragrafo, nella barra laterale, in modalità progettazione ecc.) per funzionare senza modifiche. Le pagine che si basano sul rendering lato client, come quelle per le app, non funzionano bene in modalità di creazione AEM.
Tenete presente che template.jsp include è racchiuso in un div elemento che contiene la ng-controller direttiva. Questa struttura consente il collegamento dei contenuti DOM con il controller. Pertanto, anche se le pagine che si presentano sul lato client non vanno a buon fine, i singoli componenti che lo fanno funzionano correttamente (vedere la sezione sui componenti di seguito).
<div ng-controller="<c:out value="${controllerNameStripped}"/>">
      <cq:include script="template.jsp"/>
</div>

Modalità di pubblicazione
In modalità di pubblicazione (ad esempio, quando l’app viene esportata tramite Content Sync), tutte le pagine diventano un’app a pagina singola (SPA). (Per informazioni sugli SPA, utilizzate l’esercitazione Angular, in particolare https://docs.angularjs.org/tutorial/step_07 .)
Una pagina HTML contiene un solo elemento (una pagina contenente l’ <html> elemento). Questa pagina è nota come "modello di layout". In terminologia angolare, è "...un modello comune per tutte le viste della nostra applicazione." Considerate questa pagina come "pagina dell'app di livello principale". Per convenzione, la pagina dell'app di livello principale è il cq:Page nodo dell'applicazione più vicino alla radice (e non è un reindirizzamento).
Poiché l’URI effettivo dell’app non cambia in modalità di pubblicazione, i riferimenti a risorse esterne da questa pagina devono utilizzare percorsi relativi. Di conseguenza, quando si esegue il rendering delle immagini per l’esportazione viene fornito un componente immagine speciale che tiene conto di questa pagina di livello principale.
In quanto app per layout, questa pagina di modello genera semplicemente un elemento div con una direttiva ng-view.
 <div ng-view ng-class="transition"></div>

Il servizio di route angolare utilizza questo elemento per visualizzare il contenuto di ogni pagina dell'app, incluso il contenuto autorizzabile della pagina corrente (contenuto in template.jsp).
Il file body.jsp include header.jsp e footer.jsp vuoti. Se desiderate fornire contenuto statico su ogni pagina, potete ignorare questi script nell'app.
Infine, i clientlibs javascript sono inclusi nella parte inferiore dell'elemento <body>, inclusi due file JS speciali generati sul server: <nome pagina> .angular-app-module.js e <nome pagina> .angular-app-controller.js.

angular-app-module.js.jsp

Questo script definisce il modulo Angular dell'applicazione. L'output di questo script è collegato alla marcatura generata dal resto del componente del modello tramite l' html elemento in ng-page.jsp, che contiene il seguente attributo:
ng-app="<c:out value='${applicationName}'/>"

Questo attributo indica ad Angular che il contenuto di questo elemento DOM deve essere collegato al seguente modulo. Questo modulo collega le viste (in AEM queste sarebbero risorse cq:Page) con i controller corrispondenti.
Questo modulo definisce anche un controller di livello principale denominato AppController che espone la wcmMode variabile all'ambito e configura l'URI dal quale recuperare i payload di aggiornamento della sincronizzazione dei contenuti.
Infine, questo modulo esegue un'iterazione su ciascuna pagina discendente (inclusa se stessa) ed esegue il rendering del contenuto della frazione di route di ciascuna pagina (tramite il selettore e l'estensione angular-route-fragment.js), incluso come voce di configurazione in $routeProvider di Angular. In altre parole, $routeProvider indica all'app quale contenuto eseguire il rendering quando viene richiesto un determinato percorso.

angular-route-fragment.js.jsp

Questo script genera un frammento JavaScript che deve avere il seguente modulo:
.when('/<path>', {
    templateUrl: '<path to template>',
    controller: '<controller name>'
})

Questo codice indica a $routeProvider (definito in angular-app-module.js.jsp) che '/<percorso>' deve essere gestito dalla risorsa in templateUrl e cablato da controller (che verrà raggiunto in seguito).
Se necessario, è possibile ignorare questo script per gestire percorsi più complessi, inclusi quelli con variabili. Un esempio di questo è disponibile nello script /apps/geometrixx-outdoors-app/components/angular/ng-template-page/angular-route-fragment.js.jsp installato con AEM:
// note the :id suffix on the path
.when('<c:out value="${resource.path}"/>/:id', {
    templateUrl: '<c:out value="${relativeResourcePath}"/>.template.html',
    controller: '<c:out value="${controllerNameStripped}"/>'
})

angular-app-controllers.js.jsp

In Angular, i controller collegano le variabili nell'ambito $scope, esponendole alla vista. Lo script angular-app-controllers.js.jsp segue il pattern illustrato da angular-app-module.js.jsp, in quanto esegue un'iterazione su ciascuna pagina discendente (inclusa se stessa) e genera il frammento di controller definito da ogni pagina (tramite controller.js.jsp). Il modulo che definisce è chiamato cqAppControllers e deve essere elencato come una dipendenza del modulo app di livello superiore in modo che i controller di pagina siano resi disponibili.

controller.js.jsp

Lo script controller.js.jsp genera il frammento controller per ogni pagina. Questo frammento controller ha il seguente modulo:
.controller('<c:out value="${controllerNameStripped}"/>', ['$scope', '$http',
    function($scope, $http) {
        var data = $http.get('<c:out value="${relativeResourcePath}"/>.angular.json' + cacheKiller);
 
        // component fragments which consume the contents of `data` go here
    }
])

Alla data variabile viene assegnata la promessa restituita dal $http.get metodo Angular. Ogni componente incluso in questa pagina può, se necessario, rendere disponibile del contenuto .json (tramite il relativo script angular.json.jsp) e agire sul contenuto di questa richiesta quando viene risolta. La richiesta è molto veloce su dispositivi mobili perché accede semplicemente al file system.
Affinché un componente faccia parte del controller in questo modo, deve estendere il componente /libs/mobileapps/components/angular/ng-component e includere la frameworkType: angular proprietà.

template.jsp

Introdotto nella sezione body.jsp, template.jsp contiene semplicemente parsys della pagina. In modalità di pubblicazione, a questo contenuto viene fatto riferimento direttamente (in <percorso-pagina>.template.html) e viene caricato nell'SPA tramite il templateUrl configurato in $routeProvider.
parsys in questo script può essere configurato per accettare qualsiasi tipo di componente. Tuttavia, occorre prestare attenzione quando si tratta di componenti creati per un sito Web tradizionale (anziché per un sito Web). Ad esempio, il componente Immagine di base funziona correttamente solo sulla pagina dell'app di livello principale, poiché non è progettato per fare riferimento a risorse che si trovano all'interno di un'app.

angular-module-list.js.jsp

Questo script genera semplicemente le dipendenze Angular del modulo app Angular di livello superiore. Vi viene fatto riferimento da angular-app-module.js.jsp.

header.jsp

Uno script per posizionare il contenuto statico nella parte superiore dell'app. Questo contenuto è incluso nella pagina di livello principale, al di fuori dell’ambito della visualizzazione ng.

js_clientlibs.jsp

Ignorate questo script per includere i clientlibs JavaScript.

css_clientlibs.jsp

Ignorate questo script per includere i clientlibs CSS.

Componenti per app

I componenti dell'app non devono funzionare solo su un'istanza di AEM (pubblicazione o creazione), ma anche quando il contenuto dell'applicazione viene esportato nel file system tramite Content Sync. Il componente deve pertanto includere le seguenti caratteristiche:
  • È necessario fare riferimento a tutte le risorse, i modelli e gli script di un'applicazione PhoneGap relativamente.
  • La gestione dei collegamenti è diversa se l’istanza di AEM funziona in modalità di creazione o pubblicazione.

Risorse relative

L'URI di una risorsa specifica in un'applicazione PhoneGap non differisce solo per piattaforma, ma è univoco per ogni installazione dell'app. Ad esempio, prendete nota del seguente URI di un'app in esecuzione in iOS Simulator:
file:///Users/userId/Library/Application%20Support/iPhone%20Simulator/7.0.3/Applications/24BA22ED-7D06-4330-B7EB-F6FC73251CA3/Library/files/www/content/phonegap/geometrixx/apps/ng-geometrixx-outdoors/en/home.html
Osservare il GUID '24BA22ED-7D06-4330-B7EB-F6FC73251CA3' nel percorso.
Come sviluppatore di PhoneGap, il contenuto a cui siete interessati si trova sotto la directory www. Per accedere alle risorse dell'app, usa percorsi relativi.
Per risolvere il problema, l'applicazione PhoneGap utilizza il pattern SPA (Single Page App) in modo che l'URI di base (escluso l'hash) non cambi mai. Di conseguenza, ogni risorsa, modello o script a cui si fa riferimento deve essere relativo alla pagina di livello principale. ​La pagina di primo livello inizializza il routing angolare e i controller in virtù di *<name>*.angular-app-module.js e *<name>*.angular-app-controllers.js . Questa pagina deve essere la pagina più vicina alla radice del repository che *non si estende una sling:redirect.
Sono disponibili diversi metodi helper per per gestire i percorsi relativi:
  • FrameworkContentExporterUtils.getTopLevelAppResource
  • FrameworkContentExporterUtils.getRelativePathToRootLevel
  • FrameworkContentExporterUtils.getPathToAsset
Per visualizzare esempi del loro utilizzo, aprite l'origine mobileapps disponibile in /libs/mobileapps/components/angular.

Dettagli script componente

ng-component.jsp

Questo script visualizza il contenuto del componente o un segnaposto appropriato quando viene rilevata la modalità di modifica.

template.jsp

Lo script template.jsp esegue il rendering della marcatura del componente. Se il componente in questione è guidato da dati JSON estratti da AEM (ad esempio, "ng-text"): /libs/mobileapps/components/angular/ng-text/template.jsp), questo script sarà responsabile del cablaggio della marcatura con i dati esposti dall'ambito del controller della pagina.
Tuttavia, a volte i requisiti di prestazioni stabiliscono che non è possibile eseguire modelli lato client (ovvero il binding dei dati). In questo caso, è sufficiente eseguire il rendering della marcatura del componente sul lato server e viene inclusa nel contenuto del modello di pagina.

overhead.jsp

Nei componenti guidati da dati JSON (come 'ng-text': /libs/mobileapps/components/angular/ng-text), overhead.jsp può essere utilizzato per rimuovere tutto il codice Java da template.jsp. Viene quindi fatto riferimento a template.jsp e tutte le variabili che espone sulla richiesta sono disponibili per l'uso. Questa strategia incoraggia la separazione della logica dalla presentazione e limita la quantità di codice da copiare e incollare quando un nuovo componente viene derivato da uno esistente.

controller.js.jsp

Come descritto in Modelli di pagina AEM, ogni componente può restituire un frammento JavaScript per utilizzare il contenuto JSON esposto dalla data promessa. In base alle convenzioni Angular, è consigliabile utilizzare un controller solo per assegnare variabili all'ambito.

angular.json.jsp

Questo script è incluso come frammento nel file '<page-name>.angular.json' a livello di pagina, che viene esportato per ogni pagina che estende la pagina. In questo file, lo sviluppatore di componenti può esporre qualsiasi struttura JSON richiesta dal componente. Nell’esempio "ng-text", questa struttura include semplicemente il contenuto di testo del componente e un flag che indica se il componente include o meno testo RTF.
Il componente per app Geometrixx outdoors è un esempio più complesso (/apps/geometrixx-outdoors-app/components/angular/ng-product):
{
    "content-par/ng-product": {
        "items": [{
            "name": "Cajamara",
            "description": "Bike",
            "summaryHTML": "",
            "price": "$610.00",
            "SKU": "eqsmcj",
            "numberOfLikes": "0",
            "numberOfComments": "0"
        }]
    },
    "content-par/ng-product/ng-image": {
        "items": [{
            "hasContent": true,
            "imgSrc": "home/products/eq/eqsm/eqsmcj/jcr_content/content-par/ng-product/ng-image.img.jpg/1377771306985.jpg",
            "description": "",
            "alt": "Cajamara",
            "title": "Cajamara",
            "hasLink": false,
            "linkPath": "",
            "attributes": [{
                "attributeName": "class",
                "attributeValue": "cq-dd-image"
            }]
        }]
    }
}

Contenuto del download di CLI Assets

Scaricate le risorse CLI dalla console App per ottimizzarle per una piattaforma specifica e quindi create l'app utilizzando l'API CLI (Command Line Integration) di PhoneGap. Il contenuto del file ZIP salvato nel file system locale ha la struttura seguente:
.cordova/
  |- hooks/
     |- after_prepare/
     |- before_platform_add/
     |- Other Hooks
plugins/
www/
  |- config.xml
  |- index.html
  |- res/
  |- etc/
  |- apps/
  |- content/
  |- package.json
  |- package-update.json

.cordova

Si tratta di una directory nascosta che potrebbe non essere visibile a seconda delle impostazioni del sistema operativo in uso. È necessario configurare il sistema operativo in modo che questa directory sia visibile se si prevede di modificare gli hook dell'app che contiene.

.cordova/ganci/

Questa directory contiene i ganci CLI . Le cartelle nella directory degli hook contengono script node.js che vengono eseguiti nei punti esatti durante la creazione.

.cordova/ganci/dopo-platform_add/

La directory after-platform_add contiene il copy_AMS_Conifg.js file. Questo script copia un file di configurazione per supportare la raccolta di analisi Adobe Mobile Services.

.cordova/ganci/post-preparazione/

La directory post-preparazione contiene il copy_resource_files.js file. Questo script copia una serie di immagini di icone e schermate iniziali in posizioni specifiche della piattaforma.

.cordova/ganci/before_platform_add/

La directory before_platform_add contiene il install_plugins.js file. Questo script esegue un'iterazione in un elenco di identificatori plug-in Cordova, installando quelli che rileva non sono già disponibili.
Questa strategia non richiede che i plug-in vengano raggruppati e installati in AEM ogni volta che viene eseguito il content-package:install comando Maven. La strategia alternativa per il controllo dei file nel sistema SCM richiede attività di bundling e installazione ripetitive.

.cordova/ganci/altri ganci

Includere altri ganci come necessario. Sono disponibili i seguenti ganci (forniti dall'app di esempio Phonegap hello world):
  • after_build
  • before_build
  • after_compila
  • before_compilare
  • after_docs
  • before_docs
  • after_emulate
  • before_emulate
  • after_platform_add
  • before_platform_add
  • after_platform_ls
  • before_platform_ls
  • after_platform_rm
  • before_platform_rm
  • after_plugin_add
  • before_plugin_add
  • after_plugin_ls
  • before_plugin_ls
  • after_plugin_rm
  • before_plugin_rm
  • after_Prepare
  • before_Prepare
  • after_run
  • before_run

platforms/

Questa directory è vuota finché non esegui il phonegap run <platform> comando sul progetto. Attualmente, <platform> può essere ios o android .
Dopo aver creato l'app per una piattaforma specifica, viene creata la directory corrispondente e contiene il codice dell'app specifico per la piattaforma.

plugins/

La directory dei plug-in viene compilata da ciascun plug-in elencato nel .cordova/hooks/before_platform_add/install_plugins.js file dopo l'esecuzione del phonegap run <platform> comando. La directory inizialmente è vuota.

www/

La directory www contiene tutto il contenuto Web (file HTML, JS e CSS) che implementa l'aspetto e il comportamento dell'app. Ad eccezione delle eccezioni descritte di seguito, questo contenuto proviene da AEM ed è esportato nel suo modulo statico tramite Content Sync.

www/config.xml

La documentazione di PhoneGap fa riferimento a questo file come "file di configurazione globale". Il file config.xml contiene molte proprietà dell'app, come il nome dell'app, le 'preferenze' dell'app (ad esempio, se una visualizzazione Web iOS consente o meno lo scorrimento eccessivo) e le dipendenze del plug-in che vengono utilizzate solo dalla build PhoneGap.
Il file config.xml è un file statico in AEM ed è esportato così come lo è tramite Content Sync.

www/index.html

Il file index.html viene reindirizzato alla pagina iniziale dell'app.
Il file config.xml contiene l' content elemento:
<content src="content/phonegap/geometrixx/apps/ng-geometrixx-outdoors/en.html" />
Nella documentazione docs.phonegap.comdi PhoneGap, questo elemento è descritto come "L'elemento opzionale <content> definisce la pagina iniziale dell'app nella directory delle risorse Web di livello principale. Il valore predefinito è index.html, che di solito viene visualizzato nella directory www di livello principale di un progetto."
PhoneGap build non riesce se non è presente un file index.html. Pertanto, questo file è incluso.

www/res

La directory res contiene immagini della schermata iniziale e icone. Lo copy_resource_files.js script copia i file nei percorsi specifici della piattaforma durante la fase di after_prepare creazione.

www/etc

Per convenzione, in AEM il nodo /etc contiene contenuto clientlib statico. La directory etc contiene le librerie Topcappotto, AngularJS e Geometrixx ng-clientlibsall.

www/apps

La directory delle app contiene il codice relativo alla pagina iniziale. La caratteristica unica della pagina iniziale di un'app AEM è che essa inizializza l'app senza alcuna interazione con l'utente. Il contenuto clientlib (sia CSS che JS) dell'app è quindi minimo per massimizzare le prestazioni.

www/content

La directory del contenuto contiene il resto del contenuto Web dell'app. Il contenuto può includere, ma non solo, i file seguenti:
  • Contenuto della pagina HTML, creato direttamente in AEM
  • Risorse di immagine associate ai componenti AEM
  • Contenuto JavaScript generato dagli script sul lato server
  • File JSON che descrivono il contenuto di una pagina o di un componente

www/package.json

Il file package.json è un file manifesto che elenca i file inclusi nel download di sincronizzazione dei contenuti completa . Questo file contiene anche la marca temporale in cui è stato generato il payload di sincronizzazione dei contenuti ( lastModified ). Questa proprietà viene utilizzata per richiedere aggiornamenti parziali dell'app da AEM.

www/package-update.json

Se questo payload è un download dell'intera app, il manifesto contiene l'elenco esatto dei file come package.json .
Tuttavia, se questo payload è un aggiornamento parziale, package-update.json contiene solo i file inclusi in questo payload particolare.

Passaggi successivi

Dopo aver appreso l'anatomia di un'app, consulta Applicazioni a pagina singola.