如何在Aurelia中设置Flash消息?

Mat*_*ick 1 aurelia aurelia-binding

我正在试图弄清楚如何在Aurelia制作flash消息.我已经创建了一个自定义元素flash-message并且需要它app.html但消息不会更新.如果我将其设置为默认值,它会正确显示.

app.html

<template>
  <require from="./resources/elements/flash-message"></require>
  <flash-message></flash-message>
</template>
Run Code Online (Sandbox Code Playgroud)

闪存message.html

<template>
  <div class="alert alert-success">${message}</div>
</template>
Run Code Online (Sandbox Code Playgroud)

闪存message.js

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

export class FlashMessage {
  @bindable({defaultBindingMode: bindingMode.twoWay}) message = 'Default';

  setMessage(newValue) {
    this.message = newValue;
  }
}
Run Code Online (Sandbox Code Playgroud)

对象detail.js

import {FlashMessage} from './resources/elements/flash-message';

export class ObjectDetail {
  static inject() {return [FlashMessage]};

  constructor(flash) {
    this.flash = flash;
  }

  activate(params, routeConfig) {
    this.flash.setMessage('Activate');
  }
}
Run Code Online (Sandbox Code Playgroud)

activate()代码被称为以及该setMessage()方法,但所显示的不传递消息未更新.我错过了什么?

LSt*_*rky 5

由于最初只需要模板app.html而不实例化类app.js,Aurelia将其视为自定义元素,这意味着它有自己的实例(不是单例).您基本上使用两个不同的实例FlashMessage,因此一个的属性不会反映在另一个实例中.

如果希望将它实例化为单例类,则还需要导入组件app.js并将其注入构造函数中,以便将其视为组件而不是自定义元素.

app.js

import {FlashMessage} from './resources/elements/flash-message';

@inject(FlashMessage)
export class App {
  constructor(flashMessage) {
    this.flashMessage = flashMessage;
  }
  // ...
}
Run Code Online (Sandbox Code Playgroud)

Custom Element和Class/ViewModel之间的混淆

由于所有类属性都被视为公共属性,因此您甚至不需要该setMessage(newValue)方法.您可以object-detail.js像这样更新消息属性:

this.flash.message = 'Activate';
Run Code Online (Sandbox Code Playgroud)

此外,该@bindable行旨在使用,以便您可以使用HTML代码中的变量值对其进行实例化,如下所示:

<flash-message message="Show this message"></flash-message>
Run Code Online (Sandbox Code Playgroud)

如果你不打算像这样使用它,我会跳过整@bindable行.你flash-message.js可以简化为这样:

export class FlashMessage {
  constructor() {
    this.message = 'Default';
  }
}
Run Code Online (Sandbox Code Playgroud)

使用Event Aggregator进行Flash消息

我使用Toastr第三方库实现了具有类似目标的Flash Message类(仅仅因为我喜欢UI).但是以任何你想要的方式设置它并不难.我认为,允许应用程序的任何部分设置Flash消息的最佳方法是使用Aurelia的Event Aggregator.以下代码段可能会帮助您进行设置.

闪存message.js

import { inject } from 'aurelia-framework'
import { EventAggregator } from 'aurelia-event-aggregator';

@inject(EventAggregator)
export class FlashMessage {

  constructor(eventAggregator) {
    this.eventAggregator = eventAggregator;
    this.eventAggregator.subscribe('ShowFlashMessage', this.showMessage);
  }

  showMessage(message) {
    this.message = message;
    // hide after 10 seconds
    window.setTimeout(hideMessage, 10000);
  }

  hideMessage() {
    this.message = "";
  }
}
Run Code Online (Sandbox Code Playgroud)

这显然是简化的,不会处理多条消息,或者在发布第二条消息时更新计时器,但它应该足以让您入门.

要从应用程序的其他部分设置消息,您只需先注入eventAggregator并保存在构造函数中,然后发布如下消息:

this.eventAggregator.publish('ShowFlashMessage', "Record saved");
Run Code Online (Sandbox Code Playgroud)

我在Aurelia的Toastr实施:

与您所做的类似,我创建了FlashMessage一个common在我的src文件夹中调用的子文件夹中调用的公共类.

//src/common/flash-message.js
import * as toastr from 'toastr';
import { inject } from 'aurelia-framework'
import { EventAggregator } from 'aurelia-event-aggregator';

@inject(EventAggregator)
export class FlashMessage {

    constructor(eventAggregator) {
        this.eventAggregator = eventAggregator;
        this.eventAggregator.subscribe('ewFlashSuccess', this.showSuccess);
        this.eventAggregator.subscribe('ewFlashInfo', this.showInfo);
        this.eventAggregator.subscribe('ewFlashWarning', this.showWarning);
        this.eventAggregator.subscribe('ewFlashError', this.showError);

        // Not sure why this is not working... if you figure it out, let me know.
        toastr.options = {
            positionClass: "toast-top-left",
            showEasing: "swing",
            hideEasing: "linear",
            showMethod: "fadeIn",
            hideMethod: "fadeOut",
            preventDuplicates: true,
            closeButton: true
        }
    }

    showSuccess(message) {
        toastr.success(message, null, {preventDuplicates: true, closeButton: true});
    }

    showInfo(message) {
        toastr.info(message, null, {preventDuplicates: true, closeButton: true});
    }

    showWarning(message) {
        toastr.warning(message, null, {preventDuplicates: true, closeButton: true});
    }

    showError(message) {
        toastr.error(message, null, {preventDuplicates: true, closeButton: true});
    }

}
Run Code Online (Sandbox Code Playgroud)

然后,我注入并实例化它app.js:

import { inject } from 'aurelia-framework';
import { FlashMessage } from './common/flash-message';
@inject(Core, FlashMessage)
export class App {
  constructor(core, flashMessage) {
    this.flashMessage = flashMessage;
  }
  // ...
}
Run Code Online (Sandbox Code Playgroud)

我还必须app.html像这样要求CSS :

<require from="toastr/build/toastr.min.css"></require>
Run Code Online (Sandbox Code Playgroud)

所有这一切都取决于Toastr是否正确安装(我安装了它npm install toastr --save)并且正确地需要作为依赖aurelia.json(我正在使用CLI).

                {
                    "name": "toastr",
                    "path": "../node_modules/toastr",
                    "main": "toastr",
                    "resources": [
                        "build/toastr.min.css"
                    ]
                },
Run Code Online (Sandbox Code Playgroud)

最后的想法

另请参阅Ashley Grant的回复,以便更好地解释如何获取ViewModel,以及使用GistRun来解决您的紧急问题.Ashley比Aurelia更有经验,所以如果我的部分解决方案不起作用,他最有可能!:-)

  • 如果您想采取我发布的答案并将其添加到您的免费​​中. (2认同)