Open evoactivity opened 1 week ago
Relevant context from @NullVoxPopuli:
This syntax:
const whatever = '...';
<template>
</template>
is template-only syntax.
Which uses this component manager, and has no getContext method https://github.com/glimmerjs/glimmer-vm/blob/main/packages/%40glimmer/runtime/lib/component/template-only.ts#L32
like the @glimmer/component
does: https://github.com/glimmerjs/glimmer.js/blob/v1.1.2/packages/%40glimmer/component/addon/-private/base-component-manager.ts#L57
The key here, in my mind, is that it would be nice if it were possible to pass a context to <template>
as a general API, one application of which would be to send a TestContext to the template so we can invoke this.whatever
the same way we would in the hbs
format, allowing developers to utilize the established patterns of setting up shared test context in QUnit's beforeEach hook without having to do strange workarounds like variables scoped to the module function, which would be prone to state leakage especially if we wanted to parallelize individual tests in the future.
Another potentially confusing thing here is that I believe the context setting for <template>
only happens if it's a component class, not all classes. So, while it seems unlikely someone might try to do this (the testing pattern is far more important and useful), it does present another confusing inconsistency in the developer experience:
class FooBar {
foo = 'bar';
<template>{{this.foo}}</template> // <-- cannot access this here
}
class FooBar extends Component {
foo = 'bar';
<template>{{this.foo}}</template> // <-- totally fine to access this here
}
I think one way forward, would be three phase:
this
to be set externally, at the place of usage -- with getContext from the component managers taking precedencegetContext
for @glimmer/component
and @ember/component
(the only supported classes for <template></template>
right now so that the already passed in context would be interpreted as the this
Of note, something that would still work through this process, is the XState component manager:
const Toggle = createMachine(...);
<template>
<Toggle as |blah|>
</Toggle>
</template>
because you can't extend it in any way that would give you access to a this
anyway.
This probably requires an RFC
In a class backed component a template tag has access to implicit
this
In a test context, a template tag does not have access to implicit
this
This difference in behavior can be confusing.
This has been talked about before on this PR https://github.com/emberjs/babel-plugin-ember-template-compilation/pull/40