我有一个带有“ invoke”元素的scxml事件。调用事件时,此invoke元素更新datamodel元素。我该如何定期进行?是否可以例如每秒定期调用此调用?还是每秒要过渡到事件?
后者的问题是,如果我在调用的finalize部分中放置一个过渡,进行自我调用,那么似乎不会多次调用invocation部分。
答案 0 :(得分:2)
我首先想提供有关<invoke>
的背景知识。 <invoke>
是<state>
的子代。它在进入状态时启动子状态机会话,并在退出状态时停止会话。此外,如果子会话进入<final>
状态,则会在父会话上调度done.invoke.invokeid
事件。您可以在父状态的转换中使用此done.invoke.invokeid
事件,以在子会话终止时强制退出父状态。最后,父状态和子状态可以通过<send>
相互通信。父母可以使用<send>
属性设置为target
的{{1}}与孩子进行交流,孩子可以通过_invoke_invokeid
属性设置为<send>
与父母进行交流到target
。
现在,请问您的问题:
在调用事件时,此invoke元素将更新datamodel元素。
我认为您对此进行概念化的方式可能存在问题,因为被调用的会话具有自己的数据模型(也就是说,具有自己的内存)。您可以使用_parent
绑定子会话的初始数据模型值,但实际上不能在父会话和子会话之间共享内存。这意味着您不能使用以下方式直接在子会话中更新父会话中的数据模型: <param>
或<assign>
标签。
子会话在父会话中更新数据模型的唯一方法是通过传递事件(例如<script>
)与父会话进行通信。然后,父级需要有一个<send event="update" target="_parent"><param name="dataToUpdate" expr="dataToUpdate"/></send>
元素,以便它可以处理从子会话发送的事件,例如<transition>
。
这引起了一个问题,即<transition event="update"><assign location="dataToUpdate" expr="_event.dataToUpdate"/></transition>
是否是最好的,最简单的定期更新数据模型的方法。例如,将数据模型更新逻辑放在<invoke>
状态的子级中可能更简单。这样,您可以使用<parallel>
直接更新数据模型。
我该如何定期进行?是否可以例如每秒定期调用此调用?还是每秒要过渡到事件?
要定期调用会话,您将进入和退出包含<assign>
>元素的状态。以下(未经测试的)代码可能会起作用:
<invoke
后者的问题是,如果我在调用的finalize部分中放置一个过渡,进行自我调用,那么似乎不会多次调用invocation部分。
我不认为<state id=invokeParent">
<!-- this is some data that you want the child session to update in the parent session -->
<datamodel>
<data id="dataToUpdate" />
</datamodel>
<onentry>
<send event="loop" delay="1s"/> <!-- send the 'loop' event every second to loop in invokeParent -->
</onentry>
<transition event="loop" target="invokeParent" /> <!-- this transition will exit and re-enter the state, restarting the invoked session -->
<transition event="done.invoke.myInvoke" target="invokeParent" /> <!-- also loop if the invoked session terminates -->
<invoke id="myInvoke" type="scxml" src="file:test276sub1.scxml"/> <!-- this is the invoke -->
<!-- this targetless transition handles the update event sent from the child session to the parent to update the parent's datamodel -->
<transition event="update">
<assign location="dataToUpdate" expr="_event.dataToUpdate"/>
</transition>
</state>
是transition
的合法子代。 finalize
旨在包含可执行内容(例如finalize
,script
),这些内容使您可以在父会话处理事件之前操纵子会话发送的事件。