从主导航菜单

时间:2016-12-05 14:05:48

标签: javascript aurelia aurelia-router

考虑这个例子:

主路由器位于

app.js

  • someparent / childroute1
  • someparent / childroute2
  • 路径3

“someparent”是“基本控制器和视图”。它在视图中有一些可重用的html标记,自定义元素和绑定,将由其所有“子视图和控制器”共享。子视图和控制器将访问这些。

在“someparent.html”里面(除了共享标记)还有一个<router-view>标签,其中子路由和页面应该在里面呈现,但someparent.html里面没有导航。

从app.js中的主路由器/路由中,应该可以单击链接并登陆 - 不是在父/基类“someparent”本身,而是直接在“someparent”“base / parent”的子节点上视图和控制器“,当你点击app.html导航菜单中的链接时,同时渲染这两个链接,这些链接是在app.js中的路径构建的(可能是someparent.js中的路由注入了父路由器中的子路由器或什么?)。 / p>

所以基本上我需要的是实现与基本路由几乎相同的东西 - 但正如我所提到的,我需要将多个这些路由/页面作为父视图/控制器的部分。我几乎没有找到任何关于谷歌搜索的信息,所以希望这里有人能够理解我的要求,并想知道如何在奥里利亚以正确的方式解决这个问题?

enter image description here

3 个答案:

答案 0 :(得分:1)

在更好地理解原始问题之后,我会提出以下解决方案,它利用了&#34;附加数据&#34;参数在Aurelia的路由器中可用。有关详细信息,请参阅http://aurelia.io/hub.html#/doc/article/aurelia/router/latest/router-configuration/4

<强> app.js

configureRouter(config, router) {
  this.router = router;
  config.title = 'My Application Title';
  config.map([
    { route: ['', 'home'], name: 'home', moduleId: 'homefolder/home' },
    { route: 'someparent/child1', name: 'child1', moduleId: 'someparentfolder/someparent', settings: {data: 'child1'} },
    { route: 'someparent/child2', name: 'child2', moduleId: 'someparentfolder/someparent', settings: {data: 'child2'} },
    { route: 'someparent/child3', name: 'child3', moduleId: 'someparentfolder/someparent', settings: {data: 'child3'} }
  ]);
}

<强> someparent.js

import {inject} from 'aurelia-framework';
import {Router} from 'aurelia-router';
@inject(Router)
export class SomeParent {
  constructor(router) {
    this.router = router;
  }
}

<强> someparent.html

<template>
  <require from="./child1"></require>
  <require from="./child2"></require>
  <require from="./child3"></require>

  <h1>Some Parent Page Title</h1>

  <div if.bind="router.currentInstruction.config.settings.data == 'child1'">
    <h2>Child Component 1</h2>
    <child-component-one linkeddata.bind="child1"></child-component-one>
  </div>

  <div if.bind="router.currentInstruction.config.settings.data == 'child2'">
    <h2>Child Component 2</h2>
    <child-component-two linkeddata.bind="child2"></child-component-two>
  </div>

  <div if.bind="router.currentInstruction.config.settings.data == 'child3'">
    <h2>Child Component 3</h2>
    <child-component-three linkeddata.bind="child3"></child-component-three>
  </div>

</template>

其他想法:

我测试了上面的内容并且有效。希望通过使用路由设置数据参数,您可以通过&#34;获取消息。到父路由器,看你想要显示哪个孩子。根据您的具体应用,您可能更愿意将其实现为子路由器,但只需绑定/解除绑定各个子视图,如上所述,这是一个简单的解决方案。它还向您展示了如何在Aurelia的路由器中访问您可以为每条路线提供的额外参数。

答案 1 :(得分:1)

创建一个类来包含您的共享状态,并在视图模型中依赖该类。您可以使用NewInstance.of解析程序来控制何时创建共享状态与重用。

以下是一个示例:https://gist.run?id=4cbf5e9fa71ad4f4041556e4595d3e36

enter image description here

<强>共享state.js

export class SharedState {
  fromdate = '';
  todate = '';
  language = 'English';
}

<强>共享parent.js

import {inject, NewInstance} from 'aurelia-framework';
import {SharedState} from './shared-state';

@inject(NewInstance.of(SharedState)) // <-- this says create a new instance of the SharedState whenever a SharedParent instance is created
export class SharedParent {
  constructor(state) {
    this.state = state;
  }

  configureRouter(config, router){
    config.title = 'Aurelia';
    config.map([
        { route: ['', 'child-a'], moduleId: './child-a', nav: true, title: 'Child A' },
        { route: 'child-b', moduleId: './child-b', nav: true, title: 'Child B' },
    ]);

    this.router = router;
  }
}

注意:如果您使用@inject(SharedState)代替@inject(NewInstance.of(SharedState)),则SharedState的单个实例将与所有组件共享。这可能是你正在寻找的,我不确定。 @inject(NewInstance.of(SharedState))的目的是确保父级及其子级拥有自己的SharedState实例。

儿童-a.js

import {inject} from 'aurelia-framework';
import {SharedState} from './shared-state';

@inject(SharedState)
export class ChildA {
  constructor(state) {
    this.state = state;
  }
}

儿童-b.js

import {inject} from 'aurelia-framework';
import {SharedState} from './shared-state';

@inject(SharedState)
export class ChildB {
  constructor(state) {
    this.state = state;
  }
}

答案 2 :(得分:0)

我还是相对较新的Aurelia(大约3个月),所以可能会有一个更“专家”的答案,但你想要做的是非常基本的。请记住,Aurelia完全基于组件,以至于每个组件基本上都是页面上的元素。渲染“父”视图/控制器时,“子”视图/控制器只是该父页面上的元素。因此,您只需要呈现父页面并确保子页面链接正确。

路由器(在app.js中):

configureRouter(config, router) {
  this.router = router;
  config.title = 'My Application Title';
  config.map([
    { route: ['', 'home'], name: 'home', moduleId: 'homefolder/home' },
    { route: 'someparent', name: 'someparentnamefornamedroutes-optional', moduleId: 'someparentfolder/someparent' },
  ]);
}

父ViewModel(在someparentfolder / someparent.js中)

// imports go here, like: import { inject } from 'aurelia-framework';

// injects go here, like: @inject(MyClass)
export class SomeParent {
  child1 = {
    fname: "Debbie",
    lname: "Smith"
  };
  constructor() {

  }
}

父视图(在someparentfolder / someparent.html中)

<template>
  <require from="./child1"></require>
  <require from="./child2"></require>

  <h1>Some Parent Page Title</h1>

  <h2>Child Component 1</h2>
  <child-component-one linkeddata.bind="child1"></child-component-one>

  <h2>Child Component 2</h2>
  <child-component-two></child-component-two>

</template>

Child 1 ViewModel(在someparentfolder / child1.js中)

import { inject, bindable, bindingMode } from 'aurelia-framework';
import { Core } from 'core';

@inject(Core)
export class ChildComponentOne { // use InitCaps, which will be translated to dash case by Aurelia for the element ref in SomeParent
  @bindable({ defaultBindingMode: bindingMode.twoWay }) linkeddata;
  constructor(core) {
    this.core = core;
  }
  attached() {
    // example calling core function
    var response = this.core.myCustomFunction();
  }
}

儿童1视图(在someparentfolder / child1.html中)

<template>
  <h3>Hello, ${linkeddata.fname}</h3>
  <p>Here's something from core: ${core.value1}</p>
</template>

(对Child 2 ViewModel和View使用相同的概念)

直接导航到子组件:

上面的场景将每个子组件“嵌入”在SomeParent页面中。但是,如果您只想将每个子组件打开为自己的导航路由器视图(直接在主<router-view></router-view>内容窗口中打开),只需使用如下路由器定义:

configureRouter(config, router) {
  this.router = router;
  config.title = 'My Application Title';
  config.map([
    { route: ['', 'home'], name: 'home', moduleId: 'homefolder/home' },
    { route: 'someparent', name: 'someparent', moduleId: 'someparentfolder/someparent' },
    { route: 'someparent/child1', name: 'child1', moduleId: 'someparentfolder/child1' },
    { route: 'someparent/child2', name: 'child2', moduleId: 'someparentfolder/child2' },
    { route: 'someparent/child3', name: 'child3', moduleId: 'someparentfolder/child3' }
  ]);
}

另一个场景:

也许你正在寻找的是一个Singular类,它包含一个存储状态的公共位置以及所有组件将访问的公共函数。我通过创建一个名为core.js的模型来实现这一点。我已经在上面添加了这些细节,您还可以在项目根目录(/src)文件夹中创建以下文件。

核心类(在/src/core.js中):

// Some example imports to support the common class
import { inject, noView } from 'aurelia-framework';
import { HttpClient, json } from 'aurelia-fetch-client';
import { I18N } from 'aurelia-i18n';
import { EventAggregator } from 'aurelia-event-aggregator';

@noView // this decorator is needed since there is no core.html
@inject(EventAggregator, I18N, HttpClient)
export class Core {
  value1 = "Test data 1";
  value2 = "Test data 2";
  constructor(eventAggregator, i18n, httpClient) {
    // store local handles
    this.eventAggregator = eventAggregator;
    this.i18n = i18n;
    this.httpClient = httpClient;
  }

  myCustomFunction() {
    // some code here, available to any component that has core.js injected
  }
}

关于绑定的说明:

我给出了一个如何使用JavaScript对象设置对子组件的双向绑定的示例。 Aurelia非常灵活,你可以用很多不同的方式做到这一点,但这似乎是相当标准的。如果您不需要孩子操纵child1中包含的数据,您可以删除@bindable装饰器上的括号内容,这样就可以@bindable linkeddata;

您可以添加多个参数来链接多个数据,或将它们分组到一个对象或数组中。

由于我还是一个相对较新的用户,我记得经历过这一切。如果您有任何后续意见或问题,请与我们联系。

无论如何,如果有任何真正的专家看着这个,请教我! : - )