Skip to content

StacheDefineElement Design

Kevin Phillips edited this page Jun 5, 2019 · 6 revisions

Full Example

// slider.js
import { StacheDefineElement } from "can";

class Slider extends StacheDefineElement {
  static define = {
    first: String,
    last: String,
    nameChangeCount: {
      resolve({ listenTo, resolve }) {
        let count = resolve(0);
        listenTo("fullName", () => resolve(++count));
      }
    }
  };

  get fullName() {
    return `${this.first} ${this.last}`;
  }

  static view = `
    <p>First Name: <input value:bind="first"></p>
    <p>First Name: <input value:bind="first"></p>
    <p>Full Name: {{fullName}}</p>
    <p>Name has changed {{nameChangeCount}} times!</p>
  `;
}
customElements.define("can-slide", Slider);

export default Slider;

// slider-test.js
import Slider from "./slider";
import QUnit from "steal-qunit";

QUnit.module("slider");

QUnit.test("basics", () => {
  const slider = new Slider();

  slider.addEventListener("nameChangeCount", ({ count }) => {
    assert.equal(count, 1); // not dispatched by `initialize`
  });

  slider.initialize({ first: "Kevin", last: "McCallister" });
  assert.equal(slider.fullName, "Kevin McCallister");

  slider.last = "Phillips"
  assert.equal(slider.fullName, "Kevin McCallister");

  slider.render();
  let paragraphs = slider.querySelectorAll("p");
  assert.equal(p[2].textContent, "Kevin Phillips");
  assert.equal(p[3].textContent, "Name has changed 1 times!");
});

Constructor

new ExtendedStacheDefineElement();

Issues:

Connected Callback

initialize hook

initialize({ [key:String]: Any }) { ... }
  • no events are dispatched during initialize
  • this uses the define property to set up getters/setters
  • this is an internal hook. If implemented, you must call super.initialize().

render hook

render({ [key:String]: Any }, nodeList?: NodeList ) { ... }

Issue

connect hook

connect({ [key:String]: Any }) { ... }

Disconnected Callback

disconnect hook

  • this is a user hook. If implemented, you DO NOT need to call super.disconnect().

StacheDefineElement static define

StacheDefineElement static view

Other issues

  • do we want to formalize (a finalizeClass method or something) how to call _initDefines?
  • support for passing can-bind stuff into initialize?
    • if we do, you can cause a memory leak by passing props to the constructor (if this calls initialize automatically)
  • how does stache know what method to call?
    • add a can.lifecycle (or something) symbol that points to this, which has an initialize method