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

Beyond components

Events in Qite are not tied to components. Components use events through this.events, but the underlying mechanism is generic: a Publisher can publish events and a Subscriber can capture them. This is useful when you have objects that are not components but still need to emit signals. A common example is a WebSocket connection: it receives data from the backend and you want components to handle it in a structured way.

Example: chat powered by a WebSocket connection

Suppose you have a WSConnection class that manages a WebSocket and publishes events when it receives messages. The key idea is that WSConnection is not a component, but it can still publish events and components can subscribe to them:

import Publisher from "../lib/events/publisher.js";

class WSConnection {
    constructor(url) {
        this.publisher = new Publisher("ws");

        // Sketch only -- the exact WebSocket code is not important here...
        this.ws = new WebSocket(url);
        this.ws.addEventListener("message", (e) => {
            let msg = JSON.parse(e.data);

            if (msg.type === "chat_message") {
                this.publisher.publish("message", {
                    markers: { channel: msg.channel },
                    data: msg
                });
            }
        });
    }
}

Now a chat component can subscribe to the connection.

class ChatComponent extends BaseComponent {
    constructor(tree_node, conn) {
        super(tree_node);

        // Subscribe this component to the non-component publisher
        this.events.subscribeTo(conn.publisher);

        this.events.add([
            ["message", { channel: "general" }, (msg) => {
                this.appendMessage(msg);
            }]
        ]);
    }
}

In this example, WSConnection publishes "message" events, and ChatComponent captures them like any other event. The channel marker makes it easy to filter messages without inventing separate event names. The important part, though, is not WebSockets — it's that Qite's event system can bridge non-component code and component code in a clean way.

Unsubscribing

If needed, you can always unsubscribe from the publisher later:

this.events.unsubscribeFrom(conn.publisher);

In most component code you will not need this explicitly, because components are removed from the DOM and their subscribers become inactive, but it's available when you need manual control.