Aurelia:在顶级声明自定义元素并跨应用程序访问
Aurelia: Declaring custom element at top-level and access across application
我有一个名为 loading-bar 的自定义元素,它在我的应用程序的多个页面中使用。它的目的是在加载、下载内容时显示状态消息,并为后端操作提供响应消息。
加载中-bar.html:
<template show.bind="visible">
<i class="fa fa-circle-o-notch fa-spin fa-fw" if.bind="type==1"></i>
<i class="fa fa-check fa-fw" if.bind="type==2"></i>
<span id="loading-text">${message}</span>
</template>
加载中-bar.ts:
import { customElement, bindable, bindingMode, inject } from 'aurelia-framework';
@customElement('loading-bar')
export class LoadingBarCustomElement {
private visible = false;
@bindable({ defaultBindingMode: bindingMode.twoWay }) message;
@bindable({ defaultBindingMode: bindingMode.twoWay }) type = 1;
constructor() {
this.visible = false;
}
messageChanged(newValue, oldValue) {
if (newValue && newValue !== '')
this.visible = true;
else
this.visible = false;
}
}
目前所有使用加载栏的页面都在其 html 中声明了此元素:
<loading-bar message.bind="loadMsg" type.bind="loadType"></loading-bar>
loading-Bar通过改变每个页面的loadMsg和loadType局部变量来控制。
我想做的是在适当的地方声明加载栏 html,并且能够(从任何页面)调用像 "showBar(msg, type)" 这样的方法,这将影响全局声明的加载栏。
我首先要在 app.html 中声明加载栏(就像我在此处声明的导航栏一样)并注入一个 class(在所有页面的 ViewModel 中),其中包含控制加载栏的 showBar(msg, type) 方法。
我不确定这是否是正确的前进方式,或者它的最佳实施方式,希望能提供一些帮助。
决定这样解决:
<loading-bar message.bind="lbc.loadMsg" type.bind="lbc.loadType"></loading-bar>
已添加到 app.html
创建了一个控制器class,它将用作单例:
export class LoadingBarController {
private loadMsg = '';
private loadType = 1;
public showBar(message, type) {
this.loadType = type;
this.loadMsg = message;
}
public hideBar() {
this.loadMsg = '';
}
}
这是在 app.ts(别名 "lbc")中注入的,它实际上连接到加载栏元素,并注入到要使用加载栏的页面的每个 viewModel 中.
然后通过注入的控制器控制加载栏,如下所示:
@inject(LoadingBarController)
export class ExamplePage {
constructor(private lbc: LoadingBarController){
...
}
methodUsingTheLoadingBar(){
...
this.lbc.ShowBar('Loading...', 1);
...
...
this.lbc.HideBar();
}
}
您可以使用 EventAggregator
来启用您想要执行的操作。
加载中-bar.ts
import { customElement, bindable, bindingMode, autoinject } from 'aurelia-framework';
import { EventAggregator, Subscription } from 'aurelia-event-aggregator';
@customElement('loading-bar')
@autoinject()
export class LoadingBarCustomElement {
private visible = false;
private sub1: Subscription;
private sub2: Subscription;
@bindable({ defaultBindingMode: bindingMode.twoWay }) message;
@bindable({ defaultBindingMode: bindingMode.twoWay }) type = 1;
constructor(private ea : EventAggregator ) {
this.ea = ea;
this.visible = false;
}
attached() {
this.sub1 = this.ea.subscribe('show-loading', ({ message, type }) => {
this.type = type;
this.message = message;
});
this.sub2 = this.ea.subscribe('hide-loading', () => {
this.message = '';
});
}
detached() {
this.sub1.dispose();
this.sub2.dispose();
}
messageChanged(newValue, oldValue) {
if (newValue && newValue !== '')
this.visible = true;
else
this.visible = false;
}
}
然后像这样在您的应用中的其他地方发布事件:
import {autoinject} from 'aurelia-framework';
import {EventAggregator} from 'aurelia-event-aggregator';
@autoinject()
export class ExamplePage {
constructor(private ea: EventAggregator){
...
}
async methodUsingTheLoadingBar(){
...
this.ea.publish( 'show-loading, { message: 'Loading...', type: 1 });
const foo = await getData();
...
...
this.ea.publish('hide-loading');
}
}
我有一个名为 loading-bar 的自定义元素,它在我的应用程序的多个页面中使用。它的目的是在加载、下载内容时显示状态消息,并为后端操作提供响应消息。
加载中-bar.html:
<template show.bind="visible">
<i class="fa fa-circle-o-notch fa-spin fa-fw" if.bind="type==1"></i>
<i class="fa fa-check fa-fw" if.bind="type==2"></i>
<span id="loading-text">${message}</span>
</template>
加载中-bar.ts:
import { customElement, bindable, bindingMode, inject } from 'aurelia-framework';
@customElement('loading-bar')
export class LoadingBarCustomElement {
private visible = false;
@bindable({ defaultBindingMode: bindingMode.twoWay }) message;
@bindable({ defaultBindingMode: bindingMode.twoWay }) type = 1;
constructor() {
this.visible = false;
}
messageChanged(newValue, oldValue) {
if (newValue && newValue !== '')
this.visible = true;
else
this.visible = false;
}
}
目前所有使用加载栏的页面都在其 html 中声明了此元素:
<loading-bar message.bind="loadMsg" type.bind="loadType"></loading-bar>
loading-Bar通过改变每个页面的loadMsg和loadType局部变量来控制。
我想做的是在适当的地方声明加载栏 html,并且能够(从任何页面)调用像 "showBar(msg, type)" 这样的方法,这将影响全局声明的加载栏。
我首先要在 app.html 中声明加载栏(就像我在此处声明的导航栏一样)并注入一个 class(在所有页面的 ViewModel 中),其中包含控制加载栏的 showBar(msg, type) 方法。
我不确定这是否是正确的前进方式,或者它的最佳实施方式,希望能提供一些帮助。
决定这样解决:
<loading-bar message.bind="lbc.loadMsg" type.bind="lbc.loadType"></loading-bar>
已添加到 app.html
创建了一个控制器class,它将用作单例:
export class LoadingBarController {
private loadMsg = '';
private loadType = 1;
public showBar(message, type) {
this.loadType = type;
this.loadMsg = message;
}
public hideBar() {
this.loadMsg = '';
}
}
这是在 app.ts(别名 "lbc")中注入的,它实际上连接到加载栏元素,并注入到要使用加载栏的页面的每个 viewModel 中. 然后通过注入的控制器控制加载栏,如下所示:
@inject(LoadingBarController)
export class ExamplePage {
constructor(private lbc: LoadingBarController){
...
}
methodUsingTheLoadingBar(){
...
this.lbc.ShowBar('Loading...', 1);
...
...
this.lbc.HideBar();
}
}
您可以使用 EventAggregator
来启用您想要执行的操作。
加载中-bar.ts
import { customElement, bindable, bindingMode, autoinject } from 'aurelia-framework';
import { EventAggregator, Subscription } from 'aurelia-event-aggregator';
@customElement('loading-bar')
@autoinject()
export class LoadingBarCustomElement {
private visible = false;
private sub1: Subscription;
private sub2: Subscription;
@bindable({ defaultBindingMode: bindingMode.twoWay }) message;
@bindable({ defaultBindingMode: bindingMode.twoWay }) type = 1;
constructor(private ea : EventAggregator ) {
this.ea = ea;
this.visible = false;
}
attached() {
this.sub1 = this.ea.subscribe('show-loading', ({ message, type }) => {
this.type = type;
this.message = message;
});
this.sub2 = this.ea.subscribe('hide-loading', () => {
this.message = '';
});
}
detached() {
this.sub1.dispose();
this.sub2.dispose();
}
messageChanged(newValue, oldValue) {
if (newValue && newValue !== '')
this.visible = true;
else
this.visible = false;
}
}
然后像这样在您的应用中的其他地方发布事件:
import {autoinject} from 'aurelia-framework';
import {EventAggregator} from 'aurelia-event-aggregator';
@autoinject()
export class ExamplePage {
constructor(private ea: EventAggregator){
...
}
async methodUsingTheLoadingBar(){
...
this.ea.publish( 'show-loading, { message: 'Loading...', type: 1 });
const foo = await getData();
...
...
this.ea.publish('hide-loading');
}
}