ProtoViewLogic: messageHandler()
post()
/ broadcast()
によって送られたメッセージを処理します。
開発者は派生クラスでメッセージを処理するためにこの関数をオーバーライドする必要があります。
この関数は非同期関数です。
構文
protoViewLogic.messageHandler(msg) => Promise<boolean>
引数
-
msg
:object
この関数を呼び出した呼び出し元のメソッド
post()
またはbroadcast()
から渡されるメッセージオブジェクトです。このメッセージオブジェクトには呼び出し元のメソッドによってプロパティtarget
とdeliver
が追加されています。-
id
:string
|null
メッセージの識別子です。
addActiveEvents()
で有効にしたイベント通知に対しては、イベント発生した要素への参照を持つプロパティ名が設定されます。 -
code
:string
|null
メッセージの追加の識別子です。
addActiveEvents()
で有効にしたイベント通知に対しては、発生したイベントの種別が設定されます。 -
param
:any
メッセージが持つパラメータです。DOM要素から受け取ったイベントなど、何らかの値の受け渡しに利用します。
-
origin
:any
メッセージの送信元です。
-
target
:ProtoViewLogic
メッセージの直接の送信先の
ProtoViewLogic
です。 -
deliver
:function
単一のオブジェクトを受け取り
boolean
またはPromise<boolean>
を返します。引数のオブジェクトはプロパティとしてメッセージ処理を行う関数を持ちます。
deliver()
の呼び出しに際し、id
やcode
の値に応じて引数のオブジェクトのプロパティに設定された関数が実行されます。
-
返値: Promise<boolean>
メッセージが処理されたなら true
, 未処理なら false
を返すプロミスです。
解説
このコールバックは post()
/ broadcast()
の呼び出しの中で実行されます。
ユーザは自身が実装する ProtoViewLogic
派生クラスの中でこの関数をオーバライドしなければなりません。オーバーライドしなかった場合、その ProtoViewLogic
は自身ではメッセージ処理を行いません。
対象の ProtoViewLogic
がメッセージ処理を行わなかった場合、メッセージ処理を移譲します。移譲先は呼び出し元によって異なります。
post()
の場合、親のProtoViewLogic
にメッセージ処理を移譲します。broadcast()
の場合、子のProtoViewLogic
にメッセージ処理を移譲します。
メッセージの処理は引数 msg
を介して行います。
直接 msg.id
や msg.code
に対して if
文や switch
文で分岐を表現することもできますが、ヘルパ関数 msg.deliver()
によっても msg.id
および msg.code
による分岐を表現できます。
ヘルパ関数 msg.deliver()
は副作用を持ちます。
一回目の呼び出しでは引数 handlerMap
から msg.id
にキーが一致する関数を呼び出します。ただし、msg.id
が指定されなかった場合、代わりに msg.code
に一致するキーを探し、msg.code
も指定されなかった場合、代わりに固定の文字列 "default"
に一致するキーを探します。
msg.deliver()
が msg.id
に一致する関数を探し、その呼び出しに成功した場合、次の msg.deliver()
の呼び出しでは msg.code
に一致する関数を引数 handlerMap
から探します。
同様に、msg.deliver()
が msg.code
に一致する関数を探し、その呼び出しに成功した場合、次の msg.deliver()
の呼び出しでは msg.id
に一致する関数を引数 handlerMap
から探します。
つまり、msg.deliver()
の呼び出しは交代的に msg.id
と msg.code
をキーとして使用します。
msg.id
、msg.code
、"default"
のいずれにも一致する関数が存在しなかった場合、msg.deliver()
はメッセージ未処理として false
を返します。
msg.deliver()
によるメッセージ処理の流れです。
msg.deliver(handlerMap)
find_id : Search msg.id
for handlerMap
call_id : handlerMap\[msg.id\](msg)
deliver(code) : msg.deliver(handlerMap)
find_code : Search msg.code
for handlerMap
call_code : handlerMap\[msg.code\](msg)
find_default : Search "default"
for handlerMap
call_default : handlerMap\["default"\](msg)
state process_id <msg.code
deliver(code) --> find_code
True --> [*]
False --> [*]
find_code --> call_code : Found
find_code --> find_default : Not found
call_code --> process_code : Success to call
call_code --> False : Failed to call
process_code --> True
process_code --> False
process_code --> deliver(id) : Process msg.id
find_default --> call_default : Found
find_default --> False : Not found
call_default --> process_default : Success to call
call_default --> False : Failed to call
process_default --> True
process_default --> Falsedeliver()
を利用する場合、引数 handlerMap
は msg
を引数とし boolean
を返す関数をプロパティに持つオブジェクトでなければなりません。もし handlerMap
が持つ関数が boolean
以外の値を返した場合、それは常に true
として扱われます。
messageHandler()
の返値は post()
/ broadcast()
にとってメッセージが処理されたかどうかを判断するための値となります。msg.deliver()
と同様、messageHandler()
が boolean
以外の値を返した場合、それは常に true
として扱われます。
理由がない限り deliver()
の返値と messageHandler()
の返値は一致するよう実装すべきです。
msg.deliver()
の引数 handlerMap
を定義する際には注意を払う必要があります。handlerMap
のプロパティの値をアロー関数にした場合、その中における this
はアロー関数を定義したレキシカルスコープによって定まります。一方、通常の関数にした場合、this
は handlerMap
自身となるよう deliver()
内で扱われます。
handlerMap
のプロパティとして、Function.prototype.bind()
で this
が指定された関数が渡された場合にも同様の注意が必要です。この場合、bind()
で指定されたオブジェクトが this
に設定され、これは一般には handlerMap
自身とは異なります。