Change and Changing Events

Problem Description

In the framework in a lot of places we have "change" events. For instance, on Range (Slider and Scrollbar are subclasses), there's a "change" event when the value changes. On [ListBase], there's a "selectionChange." However, we need a "changing" event in certain circumstances: 1) when the "change" is cancellable 2) when the "change" is not immediate (an effect may play in between the value being set and the value being fully committed and a "change" is dispatched).

The current list of public change events in the flex4 project are:

  • [ListBase].selectionChanging
  • [ListBase].selectionChange
  • [ListBase].itemFocusChange
  • [TextBase].selectionChange
  • [TextBase].change
  • [TextBase].changing
  • [ToggleButtonBase].change
  • [TrackBase].change
  • MXMLComponent.dataChange
  • [RichEditableText].selectionChange
  • [RichEditableText].changing
  • [RichEditableText].change
  • Spinner.change

[ScrollBar] and Slider seem to be the only two that have a default animation.

We need to decide:

  • Should we adopt a pattern for all "change" events, or just the ones that need to be cancellable and where an effect may delay the change?
  • Are the patterns for cancellable and delayed change events the exact same pattern?
  • What should the event be typed as? Should it include the value as a property of the event?

Decision

Complete this section when a decision has been made and approved

Decision Criteria

  • Some events need to be cancellable by the user. The pattern needs to allow this in certain circumstances.
  • Some events are delayed due to effects or something else. The pattern needs to publish this information so developers can know when a value is changing, but hasn't quite changed.
  • The pattern(s) should be clear and consistently applied in the framework

Proposed Solution(s):

See Recommended Solution since it's mostly just a series of small yes/no decisions.

Recommended Solution:

Do we need to always send a "changing" event for each "change" event?

No - While dispatching the changing event for every change event would be consistent, there's no need to, and it would add extra overhead for every event. Instead, only dispatch a "changing" event in places where we need it, which is where we want an event to be cancellable and where there's a delay between the start of a user-gesture and the value actually changing (because an animation has stepped in or you are dragging around). Plus, if we decide a "changing" event is needed later on, it's very easy to add.

Do all "changing" events need to be cancellable?

No - If all change events were cancellable, this would be very consistent, but in some cases, this is just unneccessary. Whether or not an event is cancellable is something very easy to document and is already included in the ASDoc template, so let's not make all changing events cancellable. If we decide later on an event should be cancellable, we can always add this behavior in.

Should we separate cancellable changing events from non-cancellable changing events so there's no confusion?

No - Whether or not the changing event is cancellable is something that's easily docced.

What should the type of the change and changing events be?

If the event is cancellable, then it must be a strongly typed event which contains both the old and new values. If the event is not cancellable, then follow the typical PARB standards when figuring out the event type. This means you could use flash.event.Event.CHANGE for the "change" event, and we'll create a [FlexEvent].CHANGING for the "changing" event.

What should be dispatched for a sequence of changes, caused by animation or caused by a user-gesture, like dragging a slider with liveDragging=true/false.

Before any work is done a "changing" event should be dispatched. For each intermediary change, a "valueCommit" event should be dispatched. After the final change a single "change" event should be dispatched. This follows the Flex pattern where "change" events are sent out when a value changes due to user-interaction. While "valueCommits" are sent out whenever the value changes due to user-interaction or through a property getting set.

If liveDragging is turned on, then the user will see "thumbPress", "changing", "thumbDrag", "valueCommit", "thumbDrag", "valueCommit", ..., "thumbDrag", "valueCommit", "thumbRelease", "change".

If liveDragging is turned off, the user will see "thumbPress", "changing", "thumbDrag", "thumbDrag", ... "thumbDrag", "change" (no intermediary valueCommits).

This is different than Halo sliders where the user would see "thumbPress", "thumbDrag", "change", "thumbDrag", "change", ..., "thumbDrag", "thumbRelease", "change" in the liveScrolling = true case.

In Halo, if liveDragging was turned off, the user would see: "thumbPress", "thumbDrag", "thumbDrag", ..., "thumbDrag", "thumbRelease", "change".

This breaks compatibility here, but we feel this new model is more consistent and matches the animation case better.

Notes:

-

You must be logged in to comment.