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