我有一个带有“invoke”元素的 scxml 事件。当事件被调用时,这个 invoke 元素更新数据模型元素。我怎样才能使这种情况定期发生?例如,是否可以每秒定期调用此调用?或者也许每秒过渡到事件?
后者的问题在于,如果我在调用的 finalize 部分中放置一个转换,调用自身,它似乎不会多次调用 invoke 部分。
我首先想提供一些关于<invoke>
. <invoke>
被放置为一个孩子<state>
。它在进入状态时启动子状态机会话,并在退出状态时停止会话。此外,如果子会话进入<final>
状态,则done.invoke.invokeid
在父会话上调度事件。您可以done.invoke.invokeid
在父状态的转换中使用此事件,以在子会话终止时强制退出父状态。最后,父子状态可以通过 相互通信<send>
。家长可以利用孩子沟通<send>
与target
属性设置为_invoke_invokeid
,和孩子可以与家长沟通,通过<send>
与target
属性设置为_parent
。
现在,回答你的问题:
当事件被调用时,这个 invoke 元素更新数据模型元素。
我认为您将其概念化的方式可能存在问题,因为被调用的会话具有自己的数据模型(也就是说,它自己的内存)。您可以使用 绑定子会话的初始数据模型值<param>
,但您不能真正在父会话和子会话之间共享内存。这意味着您不能使用 eg<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
> 元素的状态。以下(未经测试的)代码可能会起作用:
<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>
后者的问题在于,如果我在调用的 finalize 部分中放置一个转换,调用自身,它似乎不会多次调用 invoke 部分。
我不相信transition
是 的合法孩子finalize
。finalize
旨在包含可执行内容(例如script
,assign
),允许您在子会话发送的事件被父会话处理之前对其进行操作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句