Clone on Gitea
Introduction
Explained by ducks
FAQ
Getting Started
Components
Component Basics
Auto Initialization From DOM
Templates
Children and Parents
Roles
Strictness
Fields
What is a Field
Binding Fields to DOM
Reading and Writing Fields
Value Casting
Flags
Events
Overview
Event Handlers
DOM Events
Custom Events
Propagation and Flow
Advanced Event Control
Beyond Components
States
Overview
StateEngine
DisplayStateEngine
Field Matchers
Ordering and priority
Debugging
Advanced usage
Ajax
ComponentUI
VirtualForm
Unit Testing
Helpers
Overview
Cookies
Arrays

Advanced Event Control

In most components you will only use events.add(...) and events.publish(...). However, Qite's event system also provides lower-level controls that can be useful in more complex scenarios. These features are rarely needed, but when they are, they give you precise control over how events are processed.

Locking event processing

Every subscriber has a lock flag. When the lock is enabled, incoming events are queued instead of being processed immediately. When the lock is released, queued events are processed in order. This is useful when performing multi-step updates and you want to avoid intermediate handlers running too early.

Example: loan calculator with cascading updates. Suppose a loan calculator recalculates payment every time any input changes. A user drags the "duration" slider, and your component adjusts other fields based on business rules (interest tiers, origination fee, etc).

class LoanCalculatorComponent extends BaseComponent {
    constructor(tree_node) {
        super(tree_node);

        this.events.add([
            // Any change triggers recalculation
            ["field_change", "self", () => this.recalculate()],

            // Slider movement inside this component
            ["@input", ".duration", () => this.updateFromDuration()]
        ]);
    }

    updateFromDuration() {
        this.events.subscriber.lock = true;
        let duration = this.fields.get("duration");

        // Update dependent fields according to business rules
        this.fields.setOne("interest", this.interestFor(duration));
        this.fields.setOne("origination_fee", this.feeFor(duration));

        this.events.subscriber.lock = false;
    }

    recalculate() {
        // expensive calculation: amortization, rounding rules, UI updates
    }
}

Without a lock, this would cause recalculate() to run after every individual update, potentially with partially updated values. Because the subscriber is locked, those "field_change" events are queued. When the lock is released, the queued events are processed, and recalculate() runs with all fields already in a consistent state.

Locking delays event processing. Events are queued while locked and processed later in order when the lock is released. Use locking when you want to pause processing temporarily and then resume normally without losing events.

Ignoring events

A subscriber can temporarily ignore certain events.

this.events.subscriber.ignore("scan");
//
// ... do some internal work ...
//
this.events.subscriber.unignore("scan");

Ignoring prevents matching handlers from running, without removing them. You may also ignore all events by calling:

this.events.subscriber.ignore();

This is useful in rare cases where a component is in a transitional state and should not process incoming signals.

Ignoring discards events. Matching handlers do not run and the event is not queued for later execution. Use ignoring when a component is in a transitional state and certain signals should simply have no effect.

General guidance on when to use advanced controls

Locking and ignoring are tools for rare situations:

  • Batch updates.
  • Preventing re-entrancy.
  • Coordinating complex flows.

If you find yourself relying heavily on these features, reconsider your component boundaries or use the states system instead. Advanced controls exist to solve edge cases, not to replace clear component design.