This documentation is currently being moved to our new documentation site.
Please view or edit the documentation there, instead.
If you're looking for Fluid Project coordination, design, communication, etc, try the Fluid Project Wiki.
ChangeApplier API
Registering interest in model changes using a ChangeApplier
Declarative style
The declarative style for registering interest in change events uses an entry in the modelListeners options area of a modelRelayComponent. These listeners are attached to the applier during the construction process of the entire component (and its surrounding tree) and so will therefore become notified as part of the initial transaction - they will therefore get to observe the model changing state from its primordial value of undefined to holding their initial resolved value. This is the recommended way of listening to model changes using the ChangeApplier system.
Each record in the modelListeners block has the format <modelPathReference>: <modelListener declaration>. The left and right hand sides of this definition will be explained in the subsequent sections:
Model path references
A <modelPathReference> has the form:
Syntax definition for | ||
|---|---|---|
Syntax | Meaning | Examples |
Simple String | Reference to a model path in this component |
|
IoC reference | Reference to a model path in another component |
|
The 4 examples presented in the "Examples" column are parallel for the two cases - they respectively match changes occurring in the same parts of the target model, only in the first row they match into the model attached to this component (the same one in which the modelListeners record appears) and in the second row they match into the model attached to another component - one referenced by the Context Expression otherComponent.
Model listener declaration
A model listener declaration block has exactly the same form and meaning as any of the record types supported by Invokers and Listeners - including the one-string compact syntax documented with Invokers. The only difference is that an extra context name is available in this block by the name of change. This is bound to the particular change event which triggered this listener. This context behaves as an object with the following fields:
Members of the | ||
|---|---|---|
Member | Type | Description |
| Any type | The new value which is now held at the model path matched by this model listener block |
| Any type | The previous value which was held at the matched model path, before it was overwritten by the change being listened to |
|
| The path at which this change occurred. In general this will be the same as the path registered as the |
Wildcards in model path references
The last path segment of a model path reference may or may not be "*". Whether it is "*" or not, the reference matches exactly the same set of changes - the only difference is in how they are reported. A path reference of "things" will match all changes occurring below this path segment, and report all those occurring within a single transaction as a single change. A path reference of "things.*" will match the same changes, but will report one change for each immediately nested path segment touched by the changes. For example, the following definition will log just one
fluid.defaults("examples.pathExample1, {
gradeNames: ["fluid.modelRelayComponent", "autoInit"],
modelListeners: {
things: {
funcName: "console.log",
args: ["{change}.value", "{change}.path"]
}
}
});
var that = examples.pathExample1();
that.applier.change("things", {a: 1, b: 2});
// this logs {a: 1, b: 2}, "things" to the consoleHowever, the following example which just differs in the listener path (swapping "things" for "things.*") will log two changes:
fluid.defaults("examples.pathExample2, {
gradeNames: ["fluid.modelRelayComponent", "autoInit"],
modelListeners: {
"things.*": {
funcName: "console.log",
args: ["{change}.value", "{change}.path"]
}
}
});
var that = examples.pathExample2();
that.applier.change("things", {a: 1, b: 2}); // logs 2 lines
// Line 1: 1, "things.a"
// Line 2: 2, "things.b"The standard way to be notified of any changes to the model in a single notification is to use a model path reference consisting of the empty string "". Use of "*" will react to the same changes, but will report multiple notifications for compound modifications as in the above example.
It is not currently possible to supply more than one wildcard segment per path reference, or to supply the wildcard at any position in the string other than as the last path segment.
Programmatic style
The programmatic style for registering interest in model changes uses an API exposed by the ChangeApplier on its member modelChanged that is very similar to that exposed by a standard Infusion Event - the difference is that the addListener method accepts an extra 1st argument, pathSpec - this holds the same model path reference documented in the previous section on declarative binding:
applier.modelChanged.addListener(pathSpec, listener, namespace)
applier.modelChanged.removeListener(listener)
This style of listening to changes is not recommended. Since such a listener can only be attached once a component and its applier have been fully constructed, it will miss observation of the initial transaction as well as any other model changes that have occurred up to the point where it is registered. This implies that the state of the model that it sees cannot be fully predicted without a knowledge of the entire surrounding of the component tree.
The listener is notified after the change (or set of coordinated changes) has already been applied to the model - it is too late to affect this process and so this event is not preventable. The signature for these listeners is
function listener(value, oldValue, pathSegs, changeRequests)
Parameter | Description |
|---|---|
| The new (current) model value held at the path for which this listener registered interest |
| A "snapshot" of the previous model value held at that path |
| An array of |
| A single |
Users will in many cases only be interested in the first argument in this signature.
Firing a change using a ChangeApplier
Declarative style
The declarative style for firing model changes involve a kind of IoC record that is supported in various places in component configuration, in particular as part of the definition of both Invokers and Listeners of an IoC-configured component. This style of record is recognised by its use of the special member changePath which determines which path in which component model will receive the change.
Change record for firing changes by declarative binding | |||
|---|---|---|---|
Member | Type | Description |
|
|
| The reference to the model path in a model somewhere in the component tree where the change is to be triggered. This has the same syntax as the model path references documented above for declarative listening, only wildcard forms are not supported. Four examples: |
|
| Any type | The value which should be stored at the path referenced by |
|
type | String (optional) | If this holds the value |
|