Skip to content

Instantly share code, notes, and snippets.

@wycats
Created January 7, 2019 20:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wycats/f793a106893734e6fdd86f4d8ba9da08 to your computer and use it in GitHub Desktop.
Save wycats/f793a106893734e6fdd86f4d8ba9da08 to your computer and use it in GitHub Desktop.

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:

<svg {{StockSVG}}></svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment