Vanilla JavaScript with Preact signals example
A View
is constructed with a host element: a DOM element in which child elements/views will be created:
class TextField extends View {
constructor(hostElem, nameSignal) {
super(hostElem);
this.nameSignal = nameSignal;
}
Above, the nameSignal
is a Preact signal.
In setup()
, construct the elements and sub-views:
setup() {
this.inputElem = document.createElement("input");
this.inputElem.setAttribute("type", "text");
this.inputElem.value = this.nameSignal.value;
this.inputElem.oninput = ((e) => {
let value = e.target.value;
this.nameSignal.value = value;
})
this.hostElem.appendChild(this.inputElem);
}
In update()
, update the existing elements:
update() {
this.inputElem.value = this.nameSignal.value;
}
}
The main/root view could be implemented like this, creating the necessary signals and setting up sub-views:
class AppView extends View {
constructor(hostElem) {
super(hostElem);
this.name = signal("Bob");
}
setup() {
this.addSubView(new BtnView(this.hostElem, "me"))
let b2 = new BtnView(this.hostElem, "us")
this.addSubView(b2);
let b3 = new SharedBtnView(this.hostElem, b2.count);
this.addSubView(b3);
this.addSubView(new TextField(this.hostElem, this.name));
this.addSubView(new TextField(this.hostElem, this.name));
}
}
Putting it all together:
const appElem = document.querySelector("#app");
let view = new AppView(appElem);
view.connect();
The connect()
method connects everything up. It is part of the View
superclass:
class View {
constructor(hostElem) {
this.hostElem = hostElem;
this.subViews = [];
}
connect() {
this.setup();
for (let subView of this.subViews) {
subView.connect()
}
effect(() => {
this.update();
});
}
addSubView(subView) {
this.subViews.push(subView);
}
setup() {}
update() {}
}