Aurelia中视图模型之间的接口

Jef*_*f G 2 javascript aurelia

我在同一页面上有两个视图.视图A的视图模型需要在视图B的视图模型中调用方法.Aurelia有可能吗?

另外,这是最好的方法吗?使用EventAggregator(pub/sub)在视图模型之间进行通信会更好吗?

- - - 更多细节 - - -

更具体一点,我的app.html文件中使用了一个导航栏,如下所示:

<template>

    <require from="nav-bar-view"></require>

    <nav-bar-view></nav-bar-view>

    <router-view></router-view>

</template>
Run Code Online (Sandbox Code Playgroud)

路由器视图中的视图模型需要能够更改导航栏的标题和按钮文本.

我最初的设计是使用pub/sub将更改传达给导航栏视图模型.由于这看起来有点混乱和过于复杂,我想提出一个更简单的方法.

我的最新想法是创建一个单独的NavBar类,它注入到NavBarView类和"消费者"视图模型中.

以下是代码的简化版本:

NAV-BAR-view.html:

<template>
    <div class="center">${navBar.title}</div>
</template>
Run Code Online (Sandbox Code Playgroud)

NAV-BAR-view.js:

import {inject} from 'aurelia-framework';
import {NavBar} from 'nav-bar';

@inject(NavBar)
export class NavBarView {
    constructor(navBar) {
        this.navBar = navBar;
    }
}
Run Code Online (Sandbox Code Playgroud)

NAV-bar.js:

import {singleton} from 'aurelia-framework';

@singleton()
export class NavBar {
    constructor() {
        this.title = '';
    }
}
Run Code Online (Sandbox Code Playgroud)

view.js(导航栏的消费者):

import {inject} from 'aurelia-framework';
import {NavBar} from 'nav-bar';

@inject(NavBar)
export class View {
    constructor(navBar) {
        this.navBar = navBar;
    }

    attached() {
        this.navBar.title = 'This View's Title';
    }
}
Run Code Online (Sandbox Code Playgroud)

同样,这比实际代码简单得多,但是服务器用于说明这个想法.

我已经尝试过了,它运行正常.这有意义吗?有没有更好的办法?

Jer*_*yow 5

pub/sub会工作,但我怀疑你正在寻找一些比这更有针对性的东西.

将某些内容传递给自定义元素的首选方法是通过可绑定属性.假设你有component-acomponent-bA需要在B的视图模型上调用方法.这是你可以做的:

  1. 获得对B的视图模型的引用,以便我们可以绑定它的属性和方法:
<component-b view-model.ref="b"></component-b>
Run Code Online (Sandbox Code Playgroud)
  1. 将可绑定属性添加到组件A,以便我们可以为组件A提供对B方法的引用.
import {bindable} from 'aurelia-framework';

export class ComponentA {
  @bindable sayHello;
}
Run Code Online (Sandbox Code Playgroud)
  1. 将组件A的sayHello属性绑定到B的sayHello方法.
<component-a say-hello.call="b.sayHello()"></component-a>
Run Code Online (Sandbox Code Playgroud)

这是一个可运行的例子:https://gist.run/? id = 91269472d4e6509e32123ca2a63dd9ca

编辑

根据问题中的更新信息,这是我建议的:

1.创建一个包含导航栏状态的类

export class NavState {
  title = 'some default title';
}
Run Code Online (Sandbox Code Playgroud)

2.依赖导航栏组件中的NavState

@inject(NavState)
export class NavBar {
  constructor(state) {
    this.state = state; // now you can bind to "state.title" in nav-bar.html
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

3.在需要更改标题的组件中依赖NavState.

@inject(NavState)
export class MyComponentThatChangesTheTitle {
  constructor(state) {
    this.state.title = 'something else';
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

这比将组件的viewmodel作为状态传递更灵活.例如,使用此模型,您可以在导航栏实例化之前配置标题.