Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested components with <AngleBrackets /> #428

Closed
izelnakri opened this issue Oct 28, 2018 · 12 comments
Closed

Nested components with <AngleBrackets /> #428

izelnakri opened this issue Oct 28, 2018 · 12 comments

Comments

@izelnakri
Copy link

Hi there,

I started using <AngleBrackets /> for the first time this weekend and found some important issues I would like to raise.

Previously I've been using nested components to group my form and modal window components. Example:

{{ab-modal/confirmation-window}}

<!-- or: -->

{{ab-form/input}}

<!-- which could be used after yielded on: -->

{{#ab-form model=model.blogPost as |form|}}
  {{form.input attribute="title"}}

  {{form.date attribute="publishedAt"}}

  {{#form.button "success"}}Save{{/form.button}}
{{/ab-form}}

For larger applications grouping form and modal related components under a folder make a lot of sense and encourages greater level of usability when it comes to functionality and naming.

New syntax works for block-level forms:

<Form @model=model.blogPost as |form|>
  <form.input @attribute="title" />

  <form.date @attribute="publishedAt" />

  {{#form.button "success"}}Save{{/form.button}}
</Form>

However we also need to support nested level components, which is not supported currently. I think this is a major requirement for angle-brackets components in order it to be a true replacement for curly-braced components. I suggest the following syntax:

<Modal.ConfirmationModal />

<!-- or -->

<Form.input @attribute="publishedAt" />

I can explain further why this is necessary if needed.

@rwjblue
Copy link
Member

rwjblue commented Oct 29, 2018

As I read through this issue, it's not immediately clear to me specifically being requested. It seems like you are talking about yielded contextual components based on the first template snippet (which works perfectly fine with angle bracket invocation), but then you mention the desire to invoke components nested inside directories.

More information about angle bracket invocation is being worked on by the learning team, but you can read more about them over in the RFC. Specifically, this section explains how dynamic invocations work (this would be things like a yielded contextual component e.g. <form.date attribute="publishedAt" />) then later in that section (near the end) you can see where nested invocation is specifically discussed (and ruled out).

@pixelhandler
Copy link

@izelnakri perhaps it would be worth experimenting using ember-twiddle with the syntax Robert linked to and example above. I think we can close this issue as the RFC covers the case of angle bracket invocation using a variable.

@izelnakri
Copy link
Author

izelnakri commented Dec 7, 2018

Sorry for the delay in my response.

I'm requesting subcomponent lookups(<Component.SubComponent />) for ember templates. I think this is not a nice-to-have feature but rather an essential feature to keep it compatible with curly braced components, currently we dont have this, which means I will need to keep using curly braced components and cannot/will not upgrade to angle brackets as long as I can.

I dislike using variables with let as it just adds extra lines and makes things harder to read, would be a very bad compromise in my opinion. This is what I'm suggesting:

<!-- in src/ui/routes/x/template.hbs -->
<Modal.ConfirmationModal @text=model.userDeleteConfirmationText />

<Form @model=model.user as |form|>
  <form.input attribute="username" />  <!-- This is currently supported but lack of subcomponent lookups make this very hard and hacky to implement internally when inputs have their own wrappers etc -->
</Form>

Disallowing this lookup does not lead to better source code, so framework should not discourage components under component folders. My use of subcomponents are very minimal but when I use them they solve essential problems elegantly.

I think the reason we dont have them right now is because it was simply not implemented as proof-of-concept. If the issue is something like having a global lookup context for templates, we can solve that problem separately, but I dont think this is related. Having Module-unification feature implicitly defining template contexts would make our build processes more custom thus worse, but I guess that isn't going to get implemented anyways either.

@yoavfranco
Copy link

Sorry for the delay in my response.

I'm requesting subcomponent lookups(<Component.SubComponent />) for ember templates. I think this is not a nice-to-have feature but rather an essential feature to keep it compatible with curly braced components, currently we dont have this, which means I will need to keep using curly braced components and cannot/will not upgrade to angle brackets as long as I can.

I dislike using variables with let as it just adds extra lines and makes things harder to read, would be a very bad compromise in my opinion. This is what I'm suggesting:

<!-- in src/ui/routes/x/template.hbs -->
<Modal.ConfirmationModal @text=model.userDeleteConfirmationText />

<Form @model=model.user as |form|>
  <form.input attribute="username" />  <!-- This is currently supported but lack of subcomponent lookups make this very hard and hacky to implement internally when inputs have their own wrappers etc -->
</Form>

Disallowing this lookup does not lead to better source code, so framework should not discourage components under component folders. My use of subcomponents are very minimal but when I use them they solve essential problems elegantly.

I think the reason we dont have them right now is because it was simply not implemented as proof-of-concept. If the issue is something like having a global lookup context for templates, we can solve that problem separately, but I dont think this is related. Having Module-unification feature implicitly defining template contexts would make our build processes more custom thus worse, but I guess that isn't going to get implemented anyways either.

You, my friend, have the smarts! and I support your request

@pixelhandler
Copy link

@izelnakri Ah I see, perhaps to continue the discussion of support for dot lookup with angle brackets a new RFC would have to be drafted.

<Component.SubComponent />

@rwjblue where in the RFC was this ruled out? (I see that the dot syntax was not listed as how we use angle bracket invocation for components.)

@sukima
Copy link

sukima commented Dec 29, 2018

Per RFC 0311:(bottom of section)

In today's semantics, {{foo/bar}} does not try to lookup this.foo.bar and invoke it as a component. Instead, it is used as a filesystem scoping syntax. Since this feature will be rendered unnecessary with Module Unification, we recommend apps using "slash components" to migrate to alternatives provided by Module Unification (or, alternatively, keep using curly invocations for this purpose).

(emphasis mine)

AFAICT, These are the only two options available. However, there are some problems—

Keep using curly-braces

Well this is just plain silly—Really?!

Module Unification

Per the Module Unification I believe the following will apply:

If a source module is specified and the requested type is allowed in the source module's collection, look in a namespace based on the source module's namespace + name.

Which to me means that if component A has a child component A/B then within the A template you can directly invoke B with <B> and the resolver will realize there is a B component in the A's directory structure.

This method (which to me is the preferred) has two critical problems:

  1. You can only access a namespaced component from within the parent component. Which means you cannot use a nested sub-component outside of the directory it is defined in.
  2. Module Unification is not here yet classifying this alternative suggestion as quite silly!

Conclusions

  • Use curly-braces
  • Ignore the mythical Module Unification red-herring for now
  • Attempt not to dwell on this obvious oversight

And in worse-case you could always flatten the component tree and dasherize your namespaces.

P.S. Obviously contextual components are much better but they add on a lot of complexity and overhead manually managing {{yield}} to expose them. Sometimes we may just want a little bit of convention in the system to lessen the boilerplate we need. It is promised that the Module Unification will fix this but like so many RFCs announced at EmberConf—I will not be holding my breath.

@rwjblue
Copy link
Member

rwjblue commented Jan 2, 2019

@sukima

Keep using curly-braces

Well this is just plain silly—Really?!

Why? There is nothing wrong with curly bracket invocation, its definitely not going anywhere (seems very unlikely to be fully replaced ever). The main issue with this suggestion is that you loose out on all the other features of angle bracket invocation (yes, I agree its a great feature!)...

Module Unification

  1. You can only access a namespaced component from within the parent component. Which means you cannot use a nested sub-component outside of the directory it is defined in.

The Module Unification actually proposes two different mechanisms to address this (depending on the reason you are using subdirectories in the first place).

The first is what we have collectively called "local lookup" (and is what you are talking about in the quoted text above). Local lookup style scoping is very useful when you have a specific component (or group of components) that are only used by a single parent component (and are effectively that components private collaborators).

The second is by using packages. This mechanism is very useful when you are using subdirectories as a method of grouping things together (e.g. you have a app/components/form-fields/). The idea with packages is that you would extract the group of components/helpers/modifiers/etc into packages/form-fields/ and then invoke via that namespace (the RFC proposes <form-fields::text-input />, but I'm unsure if that exact syntax will exist in the long term). To a large extent, this concept already exists and can be used today with a combination of in-repo addons (instead of packages) and an addon to allow namespacing.


  1. Module Unification is not here yet classifying this alternative suggestion as quite silly!

It is promised that the Module Unification will fix this but like so many RFCs announced at EmberConf—I will not be holding my breath.

Well, this is always true until it isn't 😄. I do apologize that the module unification roll out has taken so long, but we have discovered many many things in the process and as such have had to course correct. Some of this has resulted in new RFCs (emberjs/rfcs#309 and emberjs/rfcs#367), and a bunch more thought.

Also, it may or may not be obvious, but there are many irons in the fire at the moment that relate to the "Ember Octane" mental model (see here for what is "Ember Octane"):

As you can see, lots of these things have already shipped and we are continuing to push things...

@rwjblue
Copy link
Member

rwjblue commented Jan 2, 2019

Back on topic here though, it is extremely unlikely that we would change course from the original angle bracket invocation RFC and allow slashes during invocation. Instead we need to continue pushing forward an arbitrary template import syntax that actually solves the reported issue ("can't use nested directories with angle bracket invocation") in a much better way.

Given that this isn't a bug (the RFC specifically explains the position that was implemented), I'm going to move this issue to the RFCs repo (so that it can eventually be closed by the template imports RFC).

@rwjblue rwjblue transferred this issue from emberjs/ember.js Jan 2, 2019
@tomdale
Copy link
Member

tomdale commented Jan 8, 2019

I believe the end-game solution here is to make component imports explicit, so we don't need to conflate invocation syntax with module location information.

@tomdale
Copy link
Member

tomdale commented Jan 8, 2019

See ef4#16

@lifeart
Copy link

lifeart commented Jan 14, 2019

https://github.com/crashco/ember-template-component-import

@rwjblue
Copy link
Member

rwjblue commented May 30, 2019

This landed in #457

@rwjblue rwjblue closed this as completed May 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants