Поскольку вам требуется только шаблон в 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;
}
// ...
}
Путаница между пользовательских элементов и класса/ViewModel
Поскольку все свойства класса считаются общедоступным, не нужно даже метод setMessage(newValue)
. Вы можете обновить свойство сообщения от object-detail.js
как это:
this.flash.message = 'Activate';
Также @bindable
линии предназначена для использования, так что вы можете создать его экземпляр с переменным значением в HTML-коде, например:
<flash-message message="Show this message"></flash-message>
Если вы не планируете использовать его так, я бы пропустил всю линию @bindable
. Ваш flash-message.js
может быть упрощена только это:
export class FlashMessage {
constructor() {
this.message = 'Default';
}
}
Использование событий агрегатором для Flash-сообщения
я реализовал класс флэш-сообщение с аналогичными целями, с использованием библиотеки Toastr 3 участника (только потому, что мне понравилось пользовательский интерфейс). Но это не сложно настроить так, как вы хотите.Я считаю, что лучший подход, позволяющий любой части вашего приложения установить флеш-сообщение, - это использовать агрегатор событий Aurelia. Следующий фрагмент кода может помочь вам настроить его.
флеш-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 = "";
}
}
Это, очевидно, упрощена и не обрабатывает несколько сообщений, или возобновлять таймер, когда второе сообщение отправлено, но оно должно быть достаточно, чтобы вы начали ,
Чтобы установить сообщение из другой части вашего приложения, вы можете просто первый впрыскивать eventAggregator и сохранить в конструкторе, а затем опубликовать сообщение вроде этого:
this.eventAggregator.publish('ShowFlashMessage', "Record saved");
Моего Toastr Реализация в Aurelia:
Подобно тому, что вы сделали, я создал общий класс под названием 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});
}
}
Затем я впрыскивается и инстанцировали его в 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;
}
// ...
}
Я также должен был требовать CSS в app.html
так:
<require from="toastr/build/toastr.min.css"></require>
Все это зависит от того, с установленным Toastr
(я установил его с npm install toastr --save
) и правильно потребовался в качестве зависимости в aurelia.json
(Я использую CLI).
{
"name": "toastr",
"path": "../node_modules/toastr",
"main": "toastr",
"resources": [
"build/toastr.min.css"
]
},
Заключительные мысли
Также см ответ Эшли Гранта для лучшего объяснения получить ручку на вашей ViewModel, а также рабочую GistRun, чтобы исправить свои неотложные вопросы. Эшли гораздо более опытная, чем я с Aurelia, поэтому, если части моего решения не работают, скорее всего, это будет! :-)
Поскольку пользовательские элементы создаются с несколькими экземплярами, вы работаете с двумя разными экземплярами 'FlashMessage', поэтому свойства одного не отражаются в другом. – LStarky