Lifeline pattern:
From Tom's gist, first example:
class StickyHeader extends Component {
didInsertElement() {
this.onScroll = () => {
// ...
};
window.addEventListener("scroll", this.onScroll);
}
willDestroyElement() {
window.removeEventListener("scroll", this.onScroll);
}
}
With destructor-redux (speculative sugar):
const windowListener = lifeline((event, callback) {
window.addEventListener(event, callback);
return () => window.removeEventListener(event, callback);
});
class StickyHeader extends Component {
didInsertElement() {
this.lifeline(windowListener('scroll', this.onScroll));
}
}
From Tom's gist, second example:
class StockTicker extends Component {
@service socket;
didInsertElement() {
this.lifeline(this.socket.open());
}
}
With destructor-redux (speculative sugar):
export default class SocketService extends Service {
open() {
return new Socket();
}
}
class Socket {
constructor() {
// set up web socket
}
destroy() {
// close web socket
}
}
Tom's DOM (idempotent) example:
class StockTicker extends Component {
items = ["a", "b", "c"];
didInsertElement() {
let svg = d3.select(`#${this.elementId} svg`);
this.set("svg", svg);
this.updateSVG();
}
didUpdateAttrs() {
this.updateSVG();
}
updateSVG() {
let { svg, items } = this;
let text = svg.selectAll("text").data(items);
text
.enter()
.append("text")
.merge(text)
.text(label => label);
text.exit().remove();
}
}
With a modifier:
@modifier
class StockSVG {
constructor(element) {
this.svg = d3.select(this.element);
}
initial(items) {
this.updateSVG(items);
}
update(items) {
this.updateSVG(items);
}
updateSVG(items) {
let { svg } = this;
let text = svg.selectAll("text").data(items);
text
.enter()
.append("text")
.merge(text)
.text(label => label);
text.exit().remove();
}
}
With possible coalescing sugar:
@modifier
class StockSVG {
constructor(element) {
this.svg = d3.select(this.element);
}
render(items) {
let { svg } = this;
let text = svg.selectAll("text").data(items);
text
.enter()
.append("text")
.merge(text)
.text(label => label);
text.exit().remove();
}
}
Used like this: