【问题标题】:Aurelia - Passthrough RoutesAurelia - 直通路线
【发布时间】:2017-01-25 15:53:56
【问题描述】:

是否可以在 Aurelia 中没有关联视图模型的情况下呈现静态 HTML 片段?例如,我有一个典型的页眉、正文、页脚布局。在正文中,我有路由器视图。页脚中有一组链接,例如单击时的常见问题解答,我想在正文区域中呈现视图。

当我尝试为 faq 路由定义路由配置时,该配置期望您必须指定“moduleId:”、“redirect:”、“navigationStrategy:”或“viewPorts:”之一。

我的临时工作是创建一个不做任何事情的直通视图模型。这导致了一堆直通视图模型类。我确定我做错了什么。

我在网上找不到关于这个用例的任何帮助。任何参考将不胜感激。

【问题讨论】:

    标签: view model routes aurelia


    【解决方案1】:

    您似乎正在为路由寻找 inlineView("<your html here/>") 类型的功能,以便导航到目标路由将直接在 router-view 元素中呈现 HTML。

    aurelia-router 无法直接实现这一点,因为没有 ViewModel,就无法调用 ActivationStrategy。 Aurelia-router 想在 something 上调用canActivateactivatecanDeactivatedeactivate

    但是,如果您只是想以编程方式定义标记,并且不想为每个单独的标记声明一个 ViewModel,那么可以使用 compose 元素结合 inlineViewStrategy 巧妙地解决这个问题.

    使用这种方法,您只需要一个 View/ViewModel 对,它负责根据当前路由检索正确的 HTML,然后呈现该 HTML。 还有其他方法可以做到这一点,但 AFAIK 这种方法涉及的管道数量最少。

    当然,您还需要一个对象来存储 HTML/路由对,以及一个服务来存储/检索这些对象。

    您可以在此处查看实时工作版本(包括一些用于说明问题的 cmets): https://gist.run/?id=8c7e02ce1ee0e25d966fea33b826fe10

    app.js

    import { inject } from "aurelia-framework";
    import { Router } from "aurelia-router";
    import { FaqService } from "./faq-service";
    
    @inject(Router, FaqService)
    export class App {
      constructor(router, faqService) {
        router.configure(config => {
          config.map({ route: "", moduleId: "./empty" });
          config.map({ route: "faq/:route", moduleId: "./faq-detail" });
        });
        this.router = router;
        this.faqService = faqService;
      }
    
      openFaq(item) {
        this.router.navigate(`faq/${item.route}`);
      }
    }
    

    app.html

    <template>
      <router-view></router-view>
      <ul>
        <li repeat.for="item of faqService.faqItems" click.delegate="openFaq(item)">
          ${item.title}
        </li>
      </ul>
    </template>
    

    empty.js(只是为了方便默认空路由):

    import { inlineView } from "aurelia-framework";
    @inlineView("<template>no content</template>")
    export class Empty {}
    

    faq-service.js

    import { singleton } from "aurelia-framework";
    
    class FaqItem {
      constructor(route, title, markup) {
        this.route = route;
        this.title = title;
        this.markup = markup;
      }
    }
    
    @singleton(false)
    export class FaqService {
      constructor() {
    
        this.faqItems = [
            new FaqItem("question-1", "Question 1", "<h4>Question 1</h4><p>Answer 1</p>"),
            new FaqItem("question-2", "Question 2", "<h4>Question 2</h4><p>Answer 2</p>"),
            new FaqItem("question-3", "Question 3", "<h4>Question 3</h4><p>Answer 3</p>")
        ];
      }
    
      getByRoute(route) {
        return this.faqItems.find(i => i.route === route);
      }
    }
    

    faq-detail.js

    import { inject, InlineViewStrategy } from "aurelia-framework";
    import { FaqService } from "./faq-service";
    
    @inject(FaqService)
    export class FaqDetail {
        constructor(service) {
            this.service = service;
        }
    
        activate(param) {
    
            let item = this.service.getByRoute(param.route);
            this.viewStrategy = new InlineViewStrategy(`<template>${item.markup}</template>`)
        }
    }
    

    faq-detail.html

    <template>
        <compose view.bind="viewStrategy"></compose>
    </template>
    

    【讨论】:

    • 感谢 Fred 的详细解释。这是工作。这不起作用的一个地方是,如果项目列表来自仅自定义 HTML 元素。无法在自定义元素中访问 app.js 中的 openFaq。增强功能可能会派上用场,我正在尝试探索它。如果我成功了,我会发布一个注释。
    • Enhance 在生命周期的行为方式上为您提供了一些额外的灵活性(和复杂性),但它无法解决这个问题。它使用与 InlineViewStrategy 相同的底层视图编译器。自定义元素有自己的绑定上下文,因此您不能从自定义元素中直接访问 app.js 上的属性/方法。您可以从自定义元素中分派一个 CustomEvent 并在 app.html 中使用 .delegate 监听它。 EventAggregator 也是一个合适的候选者。
    • 再次感谢 Fred 提供了一些关于如何最好地处理它的提示。结束了一些教程,ilikekillnerds.com/2015/08/….. 仅包括此处以供参考。
    猜你喜欢
    • 2018-01-01
    • 1970-01-01
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 2018-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多