Skip to content

Instantly share code, notes, and snippets.

@chriskrycho
Created December 21, 2020 16:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chriskrycho/2e8ccf037d4c87fff96c7a87bfd0f44e to your computer and use it in GitHub Desktop.
Save chriskrycho/2e8ccf037d4c87fff96c7a87bfd0f44e to your computer and use it in GitHub Desktop.
Demonstrating how args work in Glimmer components—with no Ember/Glimmer/autotracking in sight!
class Component {
#args;
get args() {
return this.#args;
}
constructor(args) {
this.#args = args;
}
}
class Root extends Component {
user = {
name: 'Chris Krycho',
age: 33,
};
haveABirthday() {
this.user.age++;
}
changeNameTo(newName) {
this.user.name = newName;
}
}
class Profile extends Component {
constructor(args) {
super(args);
}
get description() {
return `${this.args.name} is ${this.args.age} years old`;
}
}
class ArgsHandler {
#capturedArgs;
constructor(capturedArgs) {
this.#capturedArgs = capturedArgs;
}
get(_target, prop) {
const ref = this.#capturedArgs[prop];
if (ref) {
return ref();
}
}
set(_target, property) {
throw new Error(
`You attempted to set ${String(
property
)} on the arguments of a component, helper, or modifier, but arguments are immutable!`
);
}
}
function argsProxyFor(capturedArgs) {
const target = Object.create(null);
const handler = new ArgsHandler(capturedArgs);
return new Proxy(target, handler);
}
let root = new Root();
let args = argsProxyFor({
name: () => root.user.name,
age: () => root.user.age,
});
let profile = new Profile(args);
console.log(profile.description); // "Chris Krycho is 33"
root.haveABirthday();
root.changeNameTo('C. D. Krycho');
console.log(profile.description); // "C. D. Krycho is 34"
args.name = 'Chris Krycho';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment