【问题标题】:Aurelia: Declaring custom element at top-level and access across applicationAurelia:在顶层声明自定义元素并跨应用程序访问
【发布时间】:2018-07-09 10:38:38
【问题描述】:

我有一个名为 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>

loading-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 中声明加载栏(就像在此处声明我的导航栏一样)并注入一个类(在所有页面的 ViewModel 中),其中包含 showBar(msg, type ) 方法来控制加载栏。

我不确定这是否是正确的前进方式,或者它的最佳实施方式,希望能得到一些帮助。

【问题讨论】:

    标签: aurelia custom-element


    【解决方案1】:

    您可以使用EventAggregator 来启用您想要执行的操作。

    loading-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');
        }
    }
    

    【讨论】:

    • 太棒了。我一直在寻找这样的东西!
    【解决方案2】:

    决定这样解决:

    <loading-bar message.bind="lbc.loadMsg" type.bind="lbc.loadType"></loading-bar>
    

    已添加到 app.html

    创建了一个将用作单例的控制器类:

    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”)中,它实际上连接到 loading-bar 元素,并且注入到想要使用加载栏的页面的每个 viewModel 中。 然后通过注入的控制器控制加载条,如下所示:

    @inject(LoadingBarController)
    export class ExamplePage {
        constructor(private lbc: LoadingBarController){
        ...
        }
    
        methodUsingTheLoadingBar(){
            ...
            this.lbc.ShowBar('Loading...', 1);
            ...
            ...
            this.lbc.HideBar();
        }
    }
    

    【讨论】:

    • 您应该使用 EventAggregator 来启用它。您创建的是一个紧密耦合的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 2018-03-27
    相关资源
    最近更新 更多