メインコンテンツまでスキップ
バージョン: 20 R10

Entity Events

履歴
リリース内容
20 R10touched event added

Entity events are functions that are automatically invoked by ORDA each time entities and entity attributes are manipulated (added, deleted, or modified). You can write very simple events, and then make them more sophisticated.

You cannot directly trigger event function execution. Events are called automatically by ORDA based on user actions or operations performed through code on entities and their attributes.

note Compatibility note

ORDA entity events in the datastore are equivalent to triggers in the 4D database. However, actions triggered at the 4D database level using the 4D classic language commands or standard actions do not trigger ORDA events.

概要

Event level

エンティティイベント関数は必ずEntity クラス 内で定義されます。

It can be set at the entity level and/or the attribute level (it includes computed attributes). In the first case, it will be triggered for any attributes of the entity; on the other case, it will only be triggered for the targeted attribute.

For the same event, you can define different functions for different attributes.

You can also define the same event at both attribute and entity levels. The attribute event is called first and then the entity event.

Execution in remote configurations

Usually, ORDA events are executed on the server.

In client/server configuration however, the touched() event function can be executed on the server or the client, depending on the use of local keyword. A specific implementation on the client side allows the triggering of the event on the client.

ORDA constructor() functions are always executed on the client.

他のリモート設定(例: Qodly アプリケーション、REST API リクエスト、あるいはOpen datastore を通したリクエスト) では、touched() イベント関数は必ずサーバー側で実行されます。 これはつまり、イベントがトリガーされるためには、属性がタッチされたということを必ずサーバーが"見える"ようにしておかなければならないということを意味します(以下参照)。

Summary table

以下の表は、ORDA エンティティイベントの一覧とそのルールをまとめたものです。

イベントレベルFunction name(C/S) Executed on
Entity instantiationEntityconstructor()client
Attribute touched属性event touched <attrName>()Depends on local keyword
Entityevent touched()Depends on local keyword

The constructor() function is not actually an event function but is always called when a new entity is instantiated.

event parameter

Event functions accept a single event object as parameter. When the function is called, the parameter is filled with several properties:

プロパティ名利用可能性説明
kindAlways文字列イベント名("touched")
attributeName属性に関するイベントのみ文字列Attribute name (e.g. "firstname")
dataClassNameAlways文字列Dataclass name (e.g. "Company")

Event function description

Function event touched

シンタックス

{local} Function event touched($event : Object)
{local} Function event touched <attributeName>($event : Object)
// code

This event is triggered each time a value is modified in the entity.

  • 関数をエンティティレベルで定義していた場合(第一シンタックス)、その関数はエンティティの任意の属性における変更に対してトリガーされます。
  • 関数を属性レベルで定義していた場合(第二シンタックス)、関数はその属性に対する変更に対してのみトリガーされます。

This event is triggered as soon as the 4D Server / 4D engine can detect a modification of attribute value which can be due to the following actions:

  • in client/server with the local keyword or in 4D single-user:
    • the user sets a value on a 4D form,
    • the 4D code makes an assignment with the := operator. The event is also triggered in case of self-assignment ($entity.attribute:=$entity.attribute).
  • in client/server without the local keyword: some 4D code that makes an assignment with the := operator is executed on the server.
  • local キーワードを使用しないクライアント/サーバーQodly アプリケーション および リモートデータストア: ORDA 関数(エンティティ上の関数あるいはエンティティを引数として使用する関数)を呼び出した場合にはエンティティは4D Server に受信されます。 It means that you might have to implement a refresh or preview function on the remote application that sends an ORDA request to the server and triggers the event.
  • with the REST server: the value is received on the REST server with a REST request ($method=update)

The function receives an event object as parameter.

このイベントがエラーをthrow する場合でも、進行中のアクションは停止しません。

This event is also triggered:

例題 1

You want to uppercase all text attributes of an entity when it is updated.

    //ProductsEntity class
Function event touched($event : Object)

If (Value type(This[$event.attributeName])=Is text)
This[$event.attributeName]:=Uppercase(This[$event.attributeName])
End if

例題 2

The "touched" event is useful when it is not possible to write indexed query code in Function query() for a computed attribute.

This is the case for example, when your query function has to compare the value of different attributes from the same entity with each other. You must use formulas in the returned ORDA query -- which triggers sequential queries.

To fully understand this case, let's examine the following two calculated attributes:

Function get onGoing() : Boolean
return ((This.departureDate<=Current date) & (This.arrivalDate>=Current date))

Function get sameDay() : Boolean
return (This.departureDate=This.arrivalDate)

Even though they are very similar, these functions cannot be associated with identical queries because they do not compare the same types of values. The first compares attributes to a given value, while the second compares attributes to each other.

  • For the onGoing attribute, the query function is simple to write and uses indexed attributes:
Function query onGoing($event : Object) : Object
var $operator : Text
var $myQuery : Text
var $onGoingValue : Boolean
var $parameters : Collection
$parameters:=New collection()

$operator:=$event.operator
Case of
: (($operator="=") | ($operator="==") | ($operator="==="))
$onGoingValue:=Bool($event.value)
: (($operator="!=") | ($operator="!=="))
$onGoingValue:=Not(Bool($event.value))
Else
return {query: ""; parameters: $parameters}
End case

$myQuery:=($onGoingValue) ? "departureDate <= :1 AND arrivalDate >= :1" : "departureDate > :1 OR arrivalDate < :1"
// the ORDA query string uses indexed attributes, it will be indexed
$parameters.push(Current date)
return {query: $myQuery; parameters: $parameters}
  • For the sameDay attribute, the query function requires an ORDA query based on formulas and will be sequential:
Function query sameDay($event : Object) : Text
var $operator : Text
var $sameDayValue : Boolean

$operator:=$event.operator
Case of
: (($operator="=") | ($operator="==") | ($operator="==="))
$sameDayValue:=Bool($event.value)
: (($operator="!=") | ($operator="!=="))
$sameDayValue:=Not(Bool($event.value))
Else
return ""
End case

return ($sameDayValue) ? "eval(This.departureDate = This.arrivalDate)" : "eval(This.departureDate != This.arrivalDate)"
// the ORDA query string uses a formula, it will not be indexed

  • Using a scalar sameDay attribute updated when other attributes are "touched" will save time:
    //BookingEntity class

Function event touched departureDate($event : Object)

This.sameDay:=(This.departureDate = This.arrivalDate)
//
//
Function event touched arrivalDate($event : Object)

This.sameDay:=(This.departureDate = This.arrivalDate)

Example 3 (diagram): Client/server with the local keyword:

Example 4 (diagram): Client/server without the local keyword

Example 5 (diagram): Qodly application