-
Notifications
You must be signed in to change notification settings - Fork 1
StacheDefineElement Design
Kevin Phillips edited this page Jun 5, 2019
·
6 revisions
// 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!");
});
new ExtendedStacheDefineElement();
Issues:
- ¿ what does
new MyElement(props)
do ?- answer: throws for now, decide if it should
initialize
orinitializeAndRender
later
- answer: throws for now, decide if it should
- Remove
construct
hook
- calls
initialize
,render
,connect
- props passed to
connectedCallback
get passed toinitialize
- If user overwrites
connectedCallback
, they're on their own to call super, handle disconnect, etc
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({ [key:String]: Any }, nodeList?: NodeList ) { ... }
- if
initialize
hasn't been called, calls it with props passed torender
- if called twice, doesn't do anything the second time
- optional
nodeList
can be passed and will be passed tostache()
renderer - this is an internal hook. If implemented, you must call
super.render()
.
Issue
connect({ [key:String]: Any }) { ... }
- if
render
hasn't been called, calls it with props passed toconnect
- can you return a teardown function?
- answer: yes
- this is a user hook. If implemented, you DO NOT need to call
super.connect()
.
stopListening
will be called as well as any teardown function returned byconnected
- calls
disconnect
hook
- this is a user hook. If implemented, you DO NOT need to call
super.disconnect()
.
- do we want to formalize (a
finalizeClass
method or something) how to call_initDefines
? - support for passing
can-bind
stuff intoinitialize
?- 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 tothis
, which has aninitialize
method
- add a