Periodic action
No edit summary
No edit summary
Line 1: Line 1:
A periodic action is a ViewModel action that runs automatically over and over again when the Disabled expression is False.
A periodic action is a ViewModel action that runs automatically over and over again when the Disabled expression is False.


'''<span class="col-red">Warning</span>: <u>If you have a interval shorter then several seconds (>5000) - you have to have a working Disabled expression. Read more below.</u>'''
'''<span class="col-red">Warning</span>: If you have an interval <u>shorter than</u> several seconds (>5000) - you <u>have</u> to have a working Disabled expression. Read more below.'''


==== How it works ====
=== How it works ===
In the ViewModel editor:
In the ViewModel Editor:
[[File:Example of periodic action.png|none|thumb|419x419px]]
[[File:Example of periodic action.png|none|thumb|419x419px]]


===== You typically use this for: =====
==== You typically use this for: ====
* [[BestPractices:Navigating without user interaction|Automatically navigate]] on a change in the database (for example, after login when a current user has been set).
* [[BestPractices:Navigating without user interaction|Automatically navigate]] on a change in the database (for example, after login when a current user has been set).
* Executing an action like initiating a Search query when a specified time has passed.
* Executing an action like initiating a Search query when a specified time has passed.
Line 14: Line 14:
You can also use periodic action for updating a calculated value, but you should only use periodic action for this if you're using viewmodel variables, values or collections. If all your attributes are in a modeled class, use a derived settable attribute, it's more reliable, faster and easier to understand. Read more here: [[Documentation:Derived settable attributes|Derived settable attributes]]
You can also use periodic action for updating a calculated value, but you should only use periodic action for this if you're using viewmodel variables, values or collections. If all your attributes are in a modeled class, use a derived settable attribute, it's more reliable, faster and easier to understand. Read more here: [[Documentation:Derived settable attributes|Derived settable attributes]]


===== So, if you need periodic action for updating value, read below: =====
==== So, if you need periodic action for updating value, read below: ====
*If you want the persisted attribute A to get assigned to the derived attribute B, you can do so with a periodic action that starts whenever <code>self.A<>self.B</code>. Set the Disabled expression to <code>self.A=self.B</code> (this way it does NOT run when A=B, only when A<>B). In the action expression, you then assign B to A with the expression <code>self.A:=self.B</code>. Set Interval to a number X and the disable expression will become false when B is updated; X milliseconds after B gets a new value, the action will execute, and A will now become equal to B, and then the disable expression again is true, and the action rests.
*If you want the persisted attribute A to get assigned to the derived attribute B, you can do so with a periodic action that starts whenever <code>self.A<>self.B</code>. Set the Disabled expression to <code>self.A=self.B</code> (this way it does NOT run when A=B, only when A<>B). In the action expression, you then assign B to A with the expression <code>self.A:=self.B</code>. Set Interval to a number X and the disable expression will become false when B is updated; X milliseconds after B gets a new value, the action will execute, and A will now become equal to B, and then the disable expression again is true, and the action rests.


==== You have to have a working Disabled expression ====
=== You have to have a working Disabled expression ===
For every execution of a periodic action, the client needs to call the MDrivenServer. That means that if you have a interval setting of for example a 100 ms, the client has to call the server every 100 ms, until the Disabled expression is True.
For every execution of a periodic action, the client needs to call the MDrivenServer. That means that if you have a interval setting of for example a 100 ms, the client has to call the server every 100 ms, until the Disabled expression is True.


Line 29: Line 29:
  Column.allInstances->select(c | c.IsAction and (c.ActionPeriodicityMillisec <> -1) and c.ExpressionForReadOnly.isNullOrEmpty and c.ActionToExecute.EnableExpression.isNullOrEmpty)->forEach(c|c.ExpressionForReadOnly := 'false')
  Column.allInstances->select(c | c.IsAction and (c.ActionPeriodicityMillisec <> -1) and c.ExpressionForReadOnly.isNullOrEmpty and c.ActionToExecute.EnableExpression.isNullOrEmpty)->forEach(c|c.ExpressionForReadOnly := 'false')


===== See also =====
==== See also ====
[[MDrivenServer periodic server-side actions]] which is a different thing, but usually works in conjunction with ViewModel periodic actions.
[[MDrivenServer periodic server-side actions]] which is a different thing, but usually works in conjunction with ViewModel periodic actions.
[[Category:View Model]]
[[Category:View Model]]
[[Category:Actions]]
[[Category:Actions]]
{{Edited|July|12|2024}}
{{Edited|July|12|2024}}

Revision as of 05:06, 12 June 2024

A periodic action is a ViewModel action that runs automatically over and over again when the Disabled expression is False.

Warning: If you have an interval shorter than several seconds (>5000) - you have to have a working Disabled expression. Read more below.

How it works

In the ViewModel Editor:

Example of periodic action.png

You typically use this for:

  • Automatically navigate on a change in the database (for example, after login when a current user has been set).
  • Executing an action like initiating a Search query when a specified time has passed.
  • Refreshing a view in WPF with selfVM.Refresh if, for example, your root object is in a state that changes server side.
  • Updating transient collection/association that you show on the screen.

You can also use periodic action for updating a calculated value, but you should only use periodic action for this if you're using viewmodel variables, values or collections. If all your attributes are in a modeled class, use a derived settable attribute, it's more reliable, faster and easier to understand. Read more here: Derived settable attributes

So, if you need periodic action for updating value, read below:

  • If you want the persisted attribute A to get assigned to the derived attribute B, you can do so with a periodic action that starts whenever self.A<>self.B. Set the Disabled expression to self.A=self.B (this way it does NOT run when A=B, only when A<>B). In the action expression, you then assign B to A with the expression self.A:=self.B. Set Interval to a number X and the disable expression will become false when B is updated; X milliseconds after B gets a new value, the action will execute, and A will now become equal to B, and then the disable expression again is true, and the action rests.

You have to have a working Disabled expression

For every execution of a periodic action, the client needs to call the MDrivenServer. That means that if you have a interval setting of for example a 100 ms, the client has to call the server every 100 ms, until the Disabled expression is True.

The effect is that both your client and the server might be spending all their time (and CPU) frantically calling the server. AVOID THIS.

Check the client browsers network tab to verify that this is not happening.

If you don't have an Disable-expression you will get the model error "The column XXXXX is a PeriodicAction without a Disabled-expression. When using periodic actions, you must be able to stop it.", then add a Disabled Expression in the designer, even if it's only a "False".

If you open and existing project and get a lot of errors because of this, you can open the model debugger and run this EAL code to set them all to an EAL expression of False at once.

Column.allInstances->select(c | c.IsAction and (c.ActionPeriodicityMillisec <> -1) and c.ExpressionForReadOnly.isNullOrEmpty and c.ActionToExecute.EnableExpression.isNullOrEmpty)->forEach(c|c.ExpressionForReadOnly := 'false')

See also

MDrivenServer periodic server-side actions which is a different thing, but usually works in conjunction with ViewModel periodic actions.

This page was edited 1 days ago on 06/17/2024. What links here