2016-12-22 4 views
1

私はAureliaでフラッシュメッセージを作成する方法を理解しようとしています。カスタム要素flash-messageを作成しましたが、それはapp.htmlに必要ですが、メッセージは更新されません。デフォルト値に設定すると正しく表示されます。Aureliaでフラッシュメッセージを設定するには?

app.html

<template> 
    <require from="./resources/elements/flash-message"></require> 
    <flash-message></flash-message> 
</template> 

フラッシュmessage.html

<template> 
    <div class="alert alert-success">${message}</div> 
</template> 

フラッシュmessage.js

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

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

    setMessage(newValue) { 
    this.message = newValue; 
    } 
} 

オブジェクト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'); 
    } 
} 

activate()コードならびにsetMessage()法と呼ばれているが、表示されたメッセージとして送らを更新しません。私は何が欠けていますか?

+1

カスタム要素は複数インスタンスでインスタンス化されるため、2つの異なるインスタンスの 'FlashMessage'を使用しているため、一方のプロパティは他方のインスタンスに反映されません。 – LStarky

答えて

4

最初に、app.jsでクラスをインスタンス化せずにテンプレートをapp.htmlにする必要があるため、Aureliaはそれをカスタム要素として扱います。つまり、独自のインスタンス(シングルトンではありません)を持ちます。基本的にはFlashMessageという2つの異なるインスタンスで作業しているため、一方のプロパティは他方のプロパティに反映されません。

シングルトンクラスとしてインスタンス化する場合は、にコンポーネントをインポートしてコンストラクタに挿入し、カスタム要素ではなくコンポーネントのように扱う必要があります。

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行全体をスキップします。私が気に入ったからといって(Toastrサードパーティのライブラリを使用して、同様の目標を持つフラッシュMessageクラスを実装

フラッシュ・メッセージのイベントアグリゲータの

export class FlashMessage { 
    constructor() { 
    this.message = 'Default'; 
    } 
} 

使用:あなたのflash-message.jsはちょうどこのように簡略化することができUI)。しかし、あなたが望む方法でそれを設定することは難しいことではありません。アプリのどの部分にもフラッシュメッセージを設定できるようにするには、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 = ""; 
    } 
} 

これは明らかに簡素化され、第二のメッセージが掲載されている場合、複数のメッセージを処理する、またはタイマーを更新しませんが、あなたが始めるのに十分でなければなりません。

アプリの他の部分からのメッセージを設定するには、単に最初eventAggregatorを注入して、コンストラクタで保存し、その後、このようなメッセージ公開することができます:オーレリアで

this.eventAggregator.publish('ShowFlashMessage', "Record saved"); 

マイToastrの実装を:

私はsrcフォルダのcommonというサブフォルダに、FlashMessageという共通クラスを作成しました。

//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; 
    } 
    // ... 
} 

私もこのようなapp.htmlでCSSを要求しなければならなかった:

<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を得るためのより良い説明のためのアシュリー・グラントの応答を参照してください。アシュリーは私がアウレリアにいるよりもはるかに経験が多いので、私の解決策の一部がうまくいかなければ、彼の可能性は高いです! :-)

+2

あなたが回答を取っておきたい場合は、投稿してあなたの気持ちに加えてください。 –

+0

ありがとう、あなたはあまりにも親切です!私は学び成長するような "小さな男"のためにいくつかのスペースを残していただきありがとうございます!完全に編集された回答の中に間違った意見や誤解を招くようなものがある場合は、教えてください。 – LStarky

3

view-model.ref="flash"を使用してカスタム要素のViewModelへの参照を取得することをお勧めします。 activateコールバックからこれを使用することはできませんが、ページライフサイクルのその時点でバインディングが発生していないことに注意してください。下の例ではattachedコールバックを使用しています。

はここに例を示しますhttps://gist.run?id=76ef47a5327a34560737f4ade1038305

app.html

<template> 
    <require from="./flash-message"></require> 
    <flash-message view-model.ref="flash"></flash-message> 
</template> 

app.js

export class App { 
    attached(params, routeConfig) { 
    this.flash.setMessage('Activate'); 
    } 
} 

フラッシュメッセージ。LStarkyのメッセージから、HTML

<template> 
    <div class="alert alert-success">${message}</div> 
</template> 

フラッシュmessage.js

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

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

    setMessage(newValue) { 
    this.message = newValue; 
    } 
} 
3

、私はので、私はだけではなく、そのライブラリを使用して終了する前に気づいていなかったtoastrを発見しました。

npm install toastr --save

aurelia.json(バンドル下 - >依存性)

{ 
    "name": "toastr", 
    "path": "../node_modules/toastr", 
    "main": "toastr", 
    "resources": [ 
    "build/toastr.min.css" 
    ] 
} 

app.html

<require from="toastr/build/toastr.min.css"></require> 

ビューmodel.js

import toastr from 'toastr'; 

action() { 
    toastr.success('Toastr visible!'); 
} 
+1

ええ、これは私が正直にお勧めしたものです:-)乾杯! –

+0

あなたが解決策を見つけてうれしい! – LStarky

関連する問題