添加导航和路由 navigation-routing

了解如何使用SPA页面和AEM编辑器SDK支持SPA中的多个视图。 动态导航是使用Angular路由实现的,并且已添加到现有的标题组件中。

目标

  1. 了解使用SPA编辑器时可用的SPA模型路由选项。
  2. 了解如何使用Angular路由在SPA的不同视图之间导航。
  3. 实施由AEM页面层次结构驱动的动态导航。

您将构建的内容

本章将导航菜单添加到现有Header组件。 导航菜单由AEM页面层次结构驱动,并使用导航核心组件提供的JSON模型。

已实施 导航

先决条件

查看设置本地开发环境所需的工具和说明。

获取代码

  1. 通过Git下载本教程的起点:

    code language-shell
    $ git clone git@github.com:adobe/aem-guides-wknd-spa.git
    $ cd aem-guides-wknd-spa
    $ git checkout Angular/navigation-routing-start
    
  2. 使用Maven将代码库部署到本地AEM实例:

    code language-shell
    $ mvn clean install -PautoInstallSinglePackage
    

    如果使用AEM 6.x,请添加classic配置文件:

    code language-shell
    $ mvn clean install -PautoInstallSinglePackage -Pclassic
    
  3. 为传统WKND引用站点安装完成的包。 由WKND引用站点提供的图像在WKND SPA上重复使用。 可以使用AEM包管理器安装包。

    包管理器安装wknd.all

您始终可以在GitHub上查看完成的代码,或通过切换到分支Angular/navigation-routing-solution在本地签出代码。

Inspect标题组件更新 inspect-header

在前几章中,已通过app.component.htmlHeaderComponent组件添加为纯Angular组件。 在本章中,HeaderComponent组件已从应用程序中删除,并通过模板编辑器添加。 这允许用户在AEM中配置HeaderComponent的导航菜单。

NOTE
已对代码库进行了多次CSS和JavaScript更新,以便开始本章。 为了集中讨论核心概念,未讨论代码更改的​ 所有。 您可以在此处查看全部更改。
  1. 在您选择的IDE中,打开本章的SPA入门项目。

  2. ui.frontend模块下,检查文件header.component.tsui.frontend/src/app/components/header/header.component.ts

    已进行一些更新,包括添加HeaderEditConfigMapTo以使该组件能够映射到AEM组件wknd-spa-angular/components/header

    code language-js
    /* header.component.ts */
    ...
    const HeaderEditConfig = {
        ...
    };
    
    @Component({
    selector: 'app-header',
    templateUrl: './header.component.html',
    styleUrls: ['./header.component.scss']
    })
    export class HeaderComponent implements OnInit {
    @Input() items: object[];
        ...
    }
    ...
    MapTo('wknd-spa-angular/components/header')(withRouter(Header), HeaderEditConfig);
    

    记下items@Input()注释。 items将包含从AEM传入的导航对象数组。

  3. ui.apps模块中,检查AEM Header组件的组件定义: ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/header/.content.xml

    code language-xml
    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0"
        xmlns:jcr="http://www.jcp.org/jcr/1.0"
        jcr:primaryType="cq:Component"
        jcr:title="Header"
        sling:resourceSuperType="wknd-spa-angular/components/navigation"
        componentGroup="WKND SPA Angular - Structure"/>
    

    AEM Header组件将通过sling:resourceSuperType属性继承导航核心组件的所有功能。

将HeaderComponent添加到SPA模板 add-header-template

  1. 打开浏览器并登录到AEM,http://localhost:4502/。 应该已经部署了起始代码库。

  2. 导航到​ SPA页面模板http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-page-template/structure.html

  3. 选择最外层的​ 根布局容器 ​并单击其​ 策略 ​图标。 请注意,not ​选择已解锁的​ 布局容器 ​进行创作。

    选择根布局容器策略图标

  4. 复制当前策略并创建一个名为​ SPA结构 ​的新策略:

    SPA结构策略

    在​ 允许的组件 > 常规 >下,选择​ 布局容器 ​组件。

    在​ 允许的组件 > WKND SPAANGULAR — 结构 >选择​ 标头 ​组件下:

    选择标头组件

    在​ 允许的组件 > WKND SPAANGULAR- Content >下,选择​ Image ​和​ Text ​组件。 您总共应选择4个组件。

    单击​ 完成 ​以保存更改。

  5. 刷新 ​页面。 在解锁的​ 布局容器 ​上方添加​ 标头 ​组件:

    将标头组件添加到模板

  6. 选择​ 标头 ​组件并单击其​ 策略 ​图标以编辑策略。

    单击标题策略

  7. 使用​ "WKND SPA标头" ​的​ 策略标题 ​创建新策略。

    在​ 属性 ​下:

    • 将​ 导航根 ​设置为/content/wknd-spa-angular/us/en
    • 将​ 排除根级别 ​设置为​ 1
    • 取消选中​ 收集所有子页面
    • 将​ 导航结构深度 ​设置为​ 3

    配置标头策略

    这将收集/content/wknd-spa-angular/us/en下方的导航2级。

  8. 保存更改后,您应该会看到模板中已填充的Header

    填充标头组件

创建子页面

接下来,在AEM中创建其他页面,这些页面将用作SPA中的不同视图。 我们还将检查AEM提供的JSON模型的层次结构。

  1. 导航到​ 站点 ​控制台: http://localhost:4502/sites.html/content/wknd-spa-angular/us/en/home。 选择​ WKND SPAAngular主页 ​并单击​ 创建 > 页面

    创建新页面

  2. 在​ 模板 ​下,选择​ SPA页面。 在​ 属性 ​下,为​ 标题 ​输入​ “页面1”,并将​ “页面1” ​作为名称。

    输入初始页面属性

    单击​ 创建,在对话框弹出窗口中单击​ 打开 ​以在AEM SPA编辑器中打开该页面。

  3. 将新的​ Text ​组件添加到主​ 布局容器。 编辑组件并使用RTE和​ H1 ​元素输入文本: "Page 1"(您必须进入全屏模式才能更改段落元素)

    示例内容页面1

    您可以随意添加其他内容,如图像。

  4. 返回到AEM Sites控制台并重复上述步骤,创建名为​ “Page 2” ​的第二个页面作为​ Page 1 ​的同级。 将内容添加到​ 第2 ​页,以便轻松识别它。

  5. 最后,创建第三个页面​ “第3页”,但作为​ 第2 ​页的​ 。 完成之后,站点层级应如下所示:

    示例站点层次结构

  6. 在新选项卡中,打开AEM提供的JSON模型API: http://localhost:4502/content/wknd-spa-angular/us/en.model.json。 首次加载SPA时会请求此JSON内容。 外部结构如下所示:

    code language-json
    {
    "language": "en",
    "title": "en",
    "templateName": "spa-app-template",
    "designPath": "/libs/settings/wcm/designs/default",
    "cssClassNames": "spa page basicpage",
    ":type": "wknd-spa-angular/components/spa",
    ":items": {},
    ":itemsOrder": [],
    ":hierarchyType": "page",
    ":path": "/content/wknd-spa-angular/us/en",
    ":children": {
        "/content/wknd-spa-angular/us/en/home": {},
        "/content/wknd-spa-angular/us/en/home/page-1": {},
        "/content/wknd-spa-angular/us/en/home/page-2": {},
        "/content/wknd-spa-angular/us/en/home/page-2/page-3": {}
        }
    }
    

    :children下,您应该会看到所创建每个页面的条目。 所有页面的内容都包含在此初始JSON请求中。 一旦实现了导航路由,由于内容在客户端已经可用,SPA的后续视图将快速加载。

    在初始JSON请求中加载SPA的​ ALL ​内容是不明智的,因为这会降低初始页面加载的速度。 接下来,我们来看看如何收集页面的层级深度。

  7. 导航到​ SPA Root ​模板,网址为: http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-app-template/structure.html

    单击​ 页面属性菜单 > 页面策略

    打开SPA根目录的页面策略

  8. SPA根 ​模板具有额外的​ 层次结构 ​选项卡,用于控制收集的JSON内容。 结构深度 ​确定网站层次结构中收集​ ​下子页面的深度。 您还可以使用​ 结构模式 ​字段根据正则表达式筛选出其他页面。

    将​ 结构深度 ​更新为​ "2"

    更新结构深度

    单击​ 完成 ​以保存对策略所做的更改。

  9. 重新打开JSON模型http://localhost:4502/content/wknd-spa-angular/us/en.model.json

    code language-json
    {
    "language": "en",
    "title": "en",
    "templateName": "spa-app-template",
    "designPath": "/libs/settings/wcm/designs/default",
    "cssClassNames": "spa page basicpage",
    ":type": "wknd-spa-angular/components/spa",
    ":items": {},
    ":itemsOrder": [],
    ":hierarchyType": "page",
    ":path": "/content/wknd-spa-angular/us/en",
    ":children": {
        "/content/wknd-spa-angular/us/en/home": {},
        "/content/wknd-spa-angular/us/en/home/page-1": {},
        "/content/wknd-spa-angular/us/en/home/page-2": {}
        }
    }
    

    请注意,页面3 ​路径已从初始JSON模型中移除: /content/wknd-spa-angular/us/en/home/page-2/page-3

    稍后,我们将观察AEM SPA Editor SDK如何动态加载其他内容。

实施导航

接下来,使用新NavigationComponent实施导航菜单。 我们可以直接在header.component.html中添加代码,但更好的做法是避免使用大型组件。 相反,实施一个以后可能会重复使用的NavigationComponent

  1. 查看http://localhost:4502/content/wknd-spa-angular/us/en.model.json上的AEM Header组件公开的JSON:

    code language-json
    ...
    "header": {
        "items": [
        {
        "level": 0,
        "active": true,
        "path": "/content/wknd-spa-angular/us/en/home",
        "description": null,
        "url": "/content/wknd-spa-angular/us/en/home.html",
        "lastModified": 1589062597083,
        "title": "WKND SPA Angular Home Page",
        "children": [
                {
                "children": [],
                "level": 1,
                "active": false,
                "path": "/content/wknd-spa-angular/us/en/home/page-1",
                "description": null,
                "url": "/content/wknd-spa-angular/us/en/home/page-1.html",
                "lastModified": 1589429385100,
                "title": "Page 1"
                },
                {
                "level": 1,
                "active": true,
                "path": "/content/wknd-spa-angular/us/en/home/page-2",
                "description": null,
                "url": "/content/wknd-spa-angular/us/en/home/page-2.html",
                "lastModified": 1589429603507,
                "title": "Page 2",
                "children": [
                    {
                    "children": [],
                    "level": 2,
                    "active": false,
                    "path": "/content/wknd-spa-angular/us/en/home/page-2/page-3",
                    "description": null,
                    "url": "/content/wknd-spa-angular/us/en/home/page-2/page-3.html",
                    "lastModified": 1589430413831,
                    "title": "Page 3"
                    }
                ],
                }
            ]
            }
        ],
    ":type": "wknd-spa-angular/components/header"
    

    AEM页面的层次特性在JSON中建模,可用于填充导航菜单。 请注意,Header组件继承了导航核心组件的所有功能,并且通过JSON公开的内容自动映射到Angular@Input注释。

  2. 打开新的终端窗口,并导航到SPA项目的ui.frontend文件夹。 使用AngularCLI工具创建新NavigationComponent

    code language-shell
    $ cd ui.frontend
    $ ng generate component components/navigation
    CREATE src/app/components/navigation/navigation.component.scss (0 bytes)
    CREATE src/app/components/navigation/navigation.component.html (25 bytes)
    CREATE src/app/components/navigation/navigation.component.spec.ts (656 bytes)
    CREATE src/app/components/navigation/navigation.component.ts (286 bytes)
    UPDATE src/app/app.module.ts (2032 bytes)
    
  3. 接下来,在新创建的components/navigation目录中使用AngularCLI创建名为NavigationLink的类:

    code language-shell
    $ cd src/app/components/navigation/
    $ ng generate class NavigationLink
    CREATE src/app/components/navigation/navigation-link.spec.ts (187 bytes)
    CREATE src/app/components/navigation/navigation-link.ts (32 bytes)
    
  4. 返回您选择的IDE并在navigation-link.ts/src/app/components/navigation/navigation-link.ts处打开文件。

    打开navigation-link.ts文件

  5. 使用以下内容填充navigation-link.ts

    code language-js
    export class NavigationLink {
    
        title: string;
        path: string;
        url: string;
        level: number;
        children: NavigationLink[];
        active: boolean;
    
        constructor(data) {
            this.path = data.path;
            this.title = data.title;
            this.url = data.url;
            this.level = data.level;
            this.active = data.active;
            this.children = data.children.map( item => {
                return new NavigationLink(item);
            });
        }
    }
    

    这是一个简单的类,用于表示单个导航链接。 在类构造函数中,我们希望data是从AEM传入的JSON对象。 此类同时在NavigationComponentHeaderComponent中使用以轻松填充导航结构。

    不执行数据转换,此类主要是为强键入JSON模型而创建的。 请注意,this.children被类型化为NavigationLink[],并且构造函数为children数组中的每个项递归创建新的NavigationLink对象。 请记住,Header的JSON模型是分层的。

  6. 打开文件navigation-link.spec.ts。 这是NavigationLink类的测试文件。 使用以下内容更新它:

    code language-js
    import { NavigationLink } from './navigation-link';
    
    describe('NavigationLink', () => {
        it('should create an instance', () => {
            const data = {
                children: [],
                level: 1,
                active: false,
                path: '/content/wknd-spa-angular/us/en/home/page-1',
                description: null,
                url: '/content/wknd-spa-angular/us/en/home/page-1.html',
                lastModified: 1589429385100,
                title: 'Page 1'
            };
            expect(new NavigationLink(data)).toBeTruthy();
        });
    });
    

    请注意,const data遵循之前针对单个链接检查的相同JSON模型。 这远远不是可靠的单元测试,但应该足以测试NavigationLink的构造函数。

  7. 打开文件navigation.component.ts。 使用以下内容更新它:

    code language-js
    import { Component, OnInit, Input } from '@angular/core';
    import { NavigationLink } from './navigation-link';
    
    @Component({
    selector: 'app-navigation',
    templateUrl: './navigation.component.html',
    styleUrls: ['./navigation.component.scss']
    })
    export class NavigationComponent implements OnInit {
    
        @Input() items: object[];
    
        constructor() { }
    
        get navigationLinks(): NavigationLink[] {
    
            if (this.items && this.items.length > 0) {
                return this.items.map(item => {
                    return new NavigationLink(item);
                });
            }
    
            return null;
        }
    
        ngOnInit() {}
    
    }
    

    NavigationComponent需要一个名为itemsobject[],它是AEM中的JSON模型。 此类公开单个方法get navigationLinks(),该方法返回NavigationLink对象的数组。

  8. 打开文件navigation.component.html并使用以下内容更新它:

    code language-html
    <ul *ngIf="navigationLinks && navigationLinks.length > 0" class="navigation__group">
        <ng-container *ngTemplateOutlet="recursiveListTmpl; context:{ links: navigationLinks }"></ng-container>
    </ul>
    

    这将生成初始<ul>并从navigation.component.ts调用get navigationLinks()方法。 <ng-container>用于调用名为recursiveListTmpl的模板,并将navigationLinks作为名为links的变量传递。

    添加下一个recursiveListTmpl

    code language-html
    <ng-template #recursiveListTmpl let-links="links">
        <li *ngFor="let link of links" class="{{'navigation__item navigation__item--' + link.level}}">
            <a [routerLink]="link.url" class="navigation__item-link" [title]="link.title" [attr.aria-current]="link.active">
                {{link.title}}
            </a>
            <ul *ngIf="link.children && link.children.length > 0">
                <ng-container *ngTemplateOutlet="recursiveListTmpl; context:{ links: link.children }"></ng-container>
            </ul>
        </li>
    </ng-template>
    

    此时将实施导航链接的其余渲染。 请注意,变量link的类型为NavigationLink,并且该类创建的所有方法/属性均可用。 已使用[routerLink],而不是正常的href属性。 这样,我们便可链接到应用程序中的特定路由,而无需刷新全页。

    如果当前link具有非空children数组,则通过创建另一个<ul>来实现导航的递归部分。

  9. 更新navigation.component.spec.ts以添加对RouterTestingModule的支持:

    code language-diff
     ...
    + import { RouterTestingModule } from '@angular/router/testing';
     ...
     beforeEach(async(() => {
        TestBed.configureTestingModule({
    +   imports: [ RouterTestingModule ],
        declarations: [ NavigationComponent ]
        })
        .compileComponents();
     }));
     ...
    

    由于该组件使用[routerLink],因此需要添加RouterTestingModule

  10. 更新navigation.component.scss以向NavigationComponent添加一些基本样式:

@import "~src/styles/variables";

$link-color: $black;
$link-hover-color: $white;
$link-background: $black;

:host-context {
    display: block;
    width: 100%;
}

.navigation__item {
    list-style: none;
}

.navigation__item-link {
    color: $link-color;
    font-size: $font-size-large;
    text-transform: uppercase;
    padding: $gutter-padding;
    display: flex;
    border-bottom: 1px solid $gray;

    &:hover {
        background: $link-background;
        color: $link-hover-color;
    }

}

更新标头组件

现在NavigationComponent已实现,必须更新HeaderComponent以引用它。

  1. 打开终端并导航到SPA项目中的ui.frontend文件夹。 启动​ webpack开发服务器

    code language-shell
    $ npm start
    
  2. 打开浏览器选项卡并导航到http://localhost:4200/

    应将​ webpack开发服务器 ​配置为从AEM (ui.frontend/proxy.conf.json)的本地实例代理JSON模型。 这样,我们就可以直接针对本教程前面介绍的在AEM中创建的内容进行编码。

    菜单切换工作

    HeaderComponent当前已实施菜单切换功能。 接下来,添加导航组件。

  3. 返回您选择的IDE,并在ui.frontend/src/app/components/header/header.component.ts处打开文件header.component.ts

  4. 更新setHomePage()方法以删除硬编码字符串并使用AEM组件传入的动态属性:

    code language-js
    /* header.component.ts */
    import { NavigationLink } from '../navigation/navigation-link';
    ...
     setHomePage() {
        if (this.hasNavigation) {
            const rootNavigationLink: NavigationLink = new NavigationLink(this.items[0]);
            this.isHome = rootNavigationLink.path === this.route.snapshot.data.path;
            this.homePageUrl = rootNavigationLink.url;
        }
    }
    ...
    

    已基于从AEM传入的导航JSON模型的根目录items[0]创建NavigationLink的新实例。 this.route.snapshot.data.path返回当前Angular路由的路径。 此值用于确定当前路由是否为​ 主页this.homePageUrl用于填充​ 徽标 ​上的锚点链接。

  5. 打开header.component.html并将导航的静态占位符替换为对新创建的NavigationComponent的引用:

    code language-diff
        <div class="header-navigation">
            <div class="navigation">
    -            Navigation Placeholder
    +           <app-navigation [items]="items"></app-navigation>
            </div>
        </div>
    

    [items]=items属性将@Input() itemsHeaderComponent传递到将构建导航的NavigationComponent

  6. 打开header.component.spec.ts并添加NavigationComponent的声明:

    code language-diff
        /* header.component.spect.ts */
    +   import { NavigationComponent } from '../navigation/navigation.component';
    
        describe('HeaderComponent', () => {
        let component: HeaderComponent;
        let fixture: ComponentFixture<HeaderComponent>;
    
        beforeEach(async(() => {
            TestBed.configureTestingModule({
            imports: [ RouterTestingModule ],
    +       declarations: [ HeaderComponent, NavigationComponent ]
            })
            .compileComponents();
        }));
    

    由于NavigationComponent现在用作HeaderComponent的一部分,因此需要将其声明为测试台的一部分。

  7. 保存对任何打开文件的更改并返回​ webpack开发服务器http://localhost:4200/

    已完成标题导航

    通过单击菜单切换打开导航,您应该会看到填充的导航链接。 您应该能够导航到SPA的不同视图。

了解SPA路由

现在导航已经实现,请在AEM中检查路由。

  1. 在IDE的ui.frontend/src/app处打开文件app-routing.module.ts

    code language-js
    /* app-routing.module.ts */
    import { AemPageDataResolver, AemPageRouteReuseStrategy } from '@adobe/cq-angular-editable-components';
    import { NgModule } from '@angular/core';
    import { RouteReuseStrategy, RouterModule, Routes, UrlMatchResult, UrlSegment } from '@angular/router';
    import { PageComponent } from './components/page/page.component';
    
    export function AemPageMatcher(url: UrlSegment[]): UrlMatchResult {
        if (url.length) {
            return {
                consumed: url,
                posParams: {
                    path: url[url.length - 1]
                }
            };
        }
    }
    
    const routes: Routes = [
        {
            matcher: AemPageMatcher,
            component: PageComponent,
            resolve: {
                path: AemPageDataResolver
            }
        }
    ];
    @NgModule({
        imports: [RouterModule.forRoot(routes)],
        exports: [RouterModule],
        providers: [
            AemPageDataResolver,
            {
            provide: RouteReuseStrategy,
            useClass: AemPageRouteReuseStrategy
            }
        ]
    })
    export class AppRoutingModule {}
    

    routes: Routes = [];数组定义Angular组件映射的路由或导航路径。

    AemPageMatcher是自定义Angular路由器UrlMatcher,它与AEM中属于此Angular应用程序一部分的页面“看起来”的任何内容相匹配。

    PageComponent是AEM中表示页面的Angular组件,用于呈现匹配的路由。 稍后将在教程中查看PageComponent

    AemPageDataResolver由AEM SPA编辑器JS SDK提供,是一个自定义Angular路由器解析程序,用于将路由URL(AEM中包含.html扩展名的路径)转换为AEM中的资源路径(页面路径减去扩展名)。

    例如,AemPageDataResolver将路由的URL content/wknd-spa-angular/us/en/home.html转换为/content/wknd-spa-angular/us/en/home的路径。 此标头用于根据JSON模型API中的路径解析页面内容。

    由AEM SPA编辑器JS SDK提供的AemPageRouteReuseStrategy是自定义RouteReuseStrategy,它阻止跨路由重用PageComponent。 否则,在导航到页面“B”时,可能会显示页面“A”中的内容。

  2. ui.frontend/src/app/components/page/处打开文件page.component.ts

    code language-js
    ...
    export class PageComponent {
        items;
        itemsOrder;
        path;
    
        constructor(
            private route: ActivatedRoute,
            private modelManagerService: ModelManagerService
        ) {
            this.modelManagerService
            .getData({ path: this.route.snapshot.data.path })
            .then(data => {
                this.path = data[Constants.PATH_PROP];
                this.items = data[Constants.ITEMS_PROP];
                this.itemsOrder = data[Constants.ITEMS_ORDER_PROP];
            });
        }
    }
    

    需要PageComponent来处理从AEM检索到的JSON,并将其用作Angular组件以呈现路由。

    由Angular路由器模块提供的ActivatedRoute包含指示应将哪个AEM页面的JSON内容加载到此Angular页面组件实例中的状态。

    ModelManagerService,基于路由获取JSON数据并将该数据映射到类变量pathitemsitemsOrder。 这些组件随后将被传递到AEMPageComponent

  3. ui.frontend/src/app/components/page/处打开文件page.component.html

    code language-html
    <aem-page
        class="structure-page"
        [attr.data-cq-page-path]="path"
        [cqPath]="path"
        [cqItems]="items"
        [cqItemsOrder]="itemsOrder">
    </aem-page>
    

    aem-page包含AEMPageComponent。 变量pathitemsitemsOrder已传递到AEMPageComponent。 通过SPA编辑器JavaScript SDK提供的AemPageComponent将对此数据进行迭代,并根据映射组件教程中显示的JSON数据动态实例化Angular组件。

    PageComponent实际上只是AEMPageComponent的代理,而正是该AEMPageComponent完成了大部分繁重的工作以将JSON模型正确映射到Angular组件。

在AEM中Inspect SPA路由

  1. 如果启动,请打开终端并停止​ webpack开发服务器。 导航到项目的根,然后使用您的Maven技能将该项目部署到AEM:

    code language-shell
    $ cd aem-guides-wknd-spa
    $ mvn clean install -PautoInstallSinglePackage
    
    note caution
    CAUTION
    angular项目启用了一些非常严格的筛选规则。 如果Maven构建失败,请检查错误并查找在列出的文件中发现的​ Lint错误。。修复过滤器发现的任何问题并重新运行Maven命令。
  2. 导航到AEM中的SPA主页: http://localhost:4502/content/wknd-spa-angular/us/en/home.html,然后打开浏览器的开发人员工具。 以下屏幕截图是从Google Chrome浏览器中捕获的。

    刷新页面,您应该会看到对/content/wknd-spa-angular/us/en.model.json(即SPA根)的XHR请求。 请注意,根据教程前面部分对SPA根模板的层级深度配置,只包含三个子页面。 这不包括​ 第3 ​页。

    初始JSON请求 — SPA根目录

  3. 在开发人员工具打开的情况下,导航到​ 第3 ​页:

    第3页导航

    请注意,已向/content/wknd-spa-angular/us/en/home/page-2/page-3.model.json发出新的XHR请求

    第3页XHR请求

    AEM模型管理器了解​ Page 3 JSON内容不可用,因此会自动触发额外的XHR请求。

  4. 继续使用各种导航链接在SPA中导航。 请注意,不会发出其他XHR请求,也不会进行全页刷新。 这使得最终用户能够快速使用SPA,并减少返回AEM的不必要请求。

    已实施 导航

  5. 通过直接导航到http://localhost:4502/content/wknd-spa-angular/us/en/home/page-2.html尝试使用深层链接。 请注意,浏览器的“后退”按钮仍可继续使用。

恭喜! congratulations

恭喜,您已了解如何通过使用SPA编辑器SDK映射到AEM页面来支持SPA中的多个视图。 已使用Angular路由实现动态导航并将其添加到Header组件。

您始终可以在GitHub上查看完成的代码,或通过切换到分支Angular/navigation-routing-solution在本地签出代码。

后续步骤 next-steps

创建自定义组件 — 了解如何创建要与AEM SPA编辑器一起使用的自定义组件。 了解如何开发创作对话框和Sling模型,以扩展JSON模型来填充自定义组件。

recommendation-more-help
e25b6834-e87f-4ff3-ba56-4cd16cdfdec4