glimmer-native icon indicating copy to clipboard operation
glimmer-native copied to clipboard

Render Component needs wrapper

Open bakerac4 opened this issue 5 years ago • 5 comments

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.

bakerac4 avatar Sep 13 '19 12:09 bakerac4

can ast transform help with it?

lifeart avatar Sep 13 '19 18:09 lifeart

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}}

lifeart avatar Sep 13 '19 19:09 lifeart

@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

lifeart avatar Sep 28 '19 19:09 lifeart

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)))
}

lifeart avatar Sep 28 '19 20:09 lifeart

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>

lifeart avatar Oct 01 '19 20:10 lifeart