glimmer-native
glimmer-native copied to clipboard
Render Component needs wrapper
When rendering a component, currently we need a wrapper template to be rendered which contains the component we actually want to render.
It seems that without the wrapper template, a new class instance of the actual component we want to render is not created. Therefore all functions and properties are undefined i.e {{this.onClick}}
is undefined.
Here is an example of a wrapper template in use
- https://github.com/bakerac4/glimmer-native/blob/master/index.ts#L82
however that not without it downsides. It means that the user has to know that the properties he passes in to the
navigate
method will be accessable using@model.{property}
instead of just@property
in the case of navigation.
This poses a larger issue however when working with ListViews. Currently you need to pass in a wrapper template, which means you basically need to pass in any arguments as a pass through to your actual component you would like to render.
For example, Right now to use a ListView you do this
<RadListView
row="7"
colSpan="2"
loadOnDemandBufferSize="16"
loadOnDemandMode={{this.loadMode}}
selectionBehavior="Press"
@items={{this.posts}}
{{on "loadMoreDataRequested" this.loadMore}}
{{on "loaded" this.listViewLoaded}}
{{on "itemSelected" this.viewPost}}
{{set "listViewLayout" this.layout true}}
>
<Template @src={{this.listViewTemplate}} @itemClicked={{this.itemClicked}}/>
</RadListView>
where listViewTemplateSource
would be something like
listViewTemplate = `<HomeFeedListItem
@item={{this.item}}
@itemClicked={{this.itemClicked}} />`;
and then Glimmer Native takes the value passed into the template for this.itemClicked
and send sit in to the listViewTemplate
when we render.
I'd like to find a way to remove the wrapper component but still have a new instance of the class component be created.
can ast transform help with it?
basically, it may be an component
helper?
listViewTemplate = `<HomeFeedListItem
@item={{this.item}}
@itemClicked={{this.itemClicked}} />`;
with ember can be rewritted as
{{#let (component HomeFeedListItem item=this.item itemClicked=this.itemClicked as |listViewTemplate |}}
<SomeComponent @someProperty={{HomeFeedListItem}} />
{{/let}}
@bakerac4
how about this logic:
<ItemsList template="my-insane-component">
<template name="my-insane-component">
<div>
Hello It's template.
</div>
</template>
</ItemsList>
->
{{register-component "my-insane-component" "{\"symbols\":[],\"statements\":[[7,\"h1\",true],[9],[0,\"Hello world\"],[10]],\"hasEval\":false}"}
<ItemsList template="my-insane-component">
</ItemsList>
->
registerComponentHelper([componentName, template]) {
this.owner.register('component:' + componentName, template);
}
I can write related handlebars transform, if this case looks nice for you
https://astexplorer.net/#/gist/ddb656974fec413fdfde80c1329645d1/36f976b32b8c37fea517b29155216457e197b8ff
templateCompileFunction
should be implemented as
const { precompile } = require('@glimmer/compiler');
const { print } = require('@glimmer/syntax');
function templateCompileFunction(node) {
return btoa(precompile(print(node)))
}
I can update AST transform to support glimmer-like syntax
<ItemsList as |template data|>
<template>
<div>
{{data.name}}
Hello It's template.
</div>
</template>
</ItemsList>