Demonstrating how args work in Glimmer components—with no Ember/Glimmer/autotracking in sight!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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