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

Make it possible to reason about content to project (content projection and content queries unification) #37319

Open
pkozlowski-opensource opened this issue May 28, 2020 · 17 comments
Labels
area: core Issues related to the framework runtime core: content projection core: queries feature Issue that requests a new feature needs: discussion Indicates than an issue is an open discussion type: use-case
Milestone

Comments

@pkozlowski-opensource
Copy link
Member

pkozlowski-opensource commented May 28, 2020

There are multiple use-cases where one would like to reason about content provided to a component (check if content was provided at all, count the number of items etc.).

To make the discussion more concrete let's consider the following markup (full runnable scenario):

<my-container>
      <my-item></my-item>
      <my-item></my-item> 
      <my-item></my-item>
</my-container>

Given this markup the <my-container> component might want to answer the following questions:

On top of this the <my-container> implementation might want to do the following (all the provided examples boil down to the ability of projecting items individually):

  • wrap each item into some markup;
  • project only 2 first items;
  • project every second item (or items in 2 separate columns);
  • etc. etc.

Achieving any of the use-cases listed above is very difficult in the current Angular and it steams from the fact that one can't reason (count, pick-up, check presence etc.) about individual items to project.

While content queries can be used, to some degree, to reason about content items individually, the content queries approach has its problems as well:

  • we end up with 2 mechanism operating on content (content queries and content projection) - those 2 mechanism have different APIs, different capabilities, need to be learnt separately etc.;
  • there is a fundamental mismatch between 2 mechanism: content projection operates on "blocks" that can't be reason about (but capture content), while content queries are good with individual items but don't capture content (we can't insert result of a content query into the DOM).

This fundamental mismatch between content projection and content queries leads to many surprising situations and use-cases that can't be implemented really. Again, here is a "typical" example: https://stackblitz.com/edit/angular-ivy-sumkgl?file=src%2Fapp%2Fapp.component.ts

In short: content projection and content queries are good mechanisms while used separately, but as soon as we try to use both mechanisms together we start to bump into serious problems.

The idea behind opening this issue is to capture use-cases that are difficult to implement and expose problems where both content queries and content projection are used together. This should open ways to designing a more powerful content projection where it is possible to reason about and project content with one API. To set expectations: there are no immediate implementation plans, we want to capture use-cases and experiment with different APIs first.

@bmtheo
Copy link

bmtheo commented Jun 9, 2020

Here is one use case with the Angular Material lib : (ref for more info : angular/components#9411)

The use case is to share some advanced form fields in an app (add features around a MatFormFieldControl) without reimplementing all the values of input

The content projection is used to project the input into the advanced form field
The content queries are used by Angular Material to manipulate the input

Rough example :

<!-- my-advanced-field.component.html -->
<mat-form-field>
  <ng-content></ng-content>
  <!-- some other features of my advanced field -->
</mat-form-field>

<!-- my-component.component.html -->
<my-advanced-field>
  <input matInput ... > <!-- This is not possible today because it needs content projection and content queries -->
</my-advanced-field>

Full example here : https://stackblitz.com/edit/angular-material2-issue-jekywv

Without this, all the values of the input used by my-component needs to be implemented by my-advanced-field resulting in large boilerplate code

@mills-andrew
Copy link

any update? Bump.

@haskelcurry
Copy link

Any updates on this?
Here's a bright issue:

<mat-form-field>
  <ng-content></ng-content>
  <mat-error>My reusable error</mat-error>
</mat-form-field>

...aand you cannot do it. And it's 2022.

@zolakt
Copy link

zolakt commented May 19, 2022

Any update on this?

Or is it going to end up the same as any other feature request that anyone has ever asked for... closed by the bot, while you continue to work on Ivy, or something else that nobody needs?

@MilesAl
Copy link

MilesAl commented Jun 2, 2022

This "feature" should be implemented as soon as possible. There are some use cases that have this issue and the larger the application scales, the more issues arise. The mat-menu becomes partially unusable or requires a lot of redundant code, which is not acceptable for enterprise applications. Please work on this issue!

@matheo
Copy link

matheo commented Aug 5, 2022

+1 here
I'm trying to programatically create a control dynamically with a wrapper
and @ContentChild cannot fetch the projected component:
image

dyn-factory.html:

<ng-container #control></ng-container>
<ng-container #wrapper></ng-container>

dyn-factory.ts:

this.controlRef = this.controlContainer.createComponent<AbstractDynControl>(controlFactory, undefined, injector);

this.wrapperRef = this.wrapperContainer.createComponent<AbstractDynWrapper>(
  wrapperFactory,
  undefined,
  injector,
  [[this.controlRef.location.nativeElement]], // <- doesn't receive a View
);

and having this simple wrapper:

<p>form-field</p>
<ng-content></ng-content>

for this simple control:

<input matInput [type]="params.type" [formControl]="control" />

works in the HTML output but the wrapper,
but as the projectable nodes are just HTML nodes and not a View to inject in the hierarchy
the Wrapper is not able to fetch the ControlComponent nor the MatFormFieldControl
via @ContentChild nor @ContentChildren(x, { descendants: true })

help with this feature please :(

@csisy
Copy link

csisy commented Aug 8, 2022

Any updates on this? Here's a bright issue:

<mat-form-field>
  <ng-content></ng-content>
  <mat-error>My reusable error</mat-error>
</mat-form-field>

...aand you cannot do it. And it's 2022.

Yep. We wanted the same thing and then found this issue which is open since May 28 2020...

@lcervo-diligent
Copy link

any updates?

@gegis
Copy link

gegis commented Nov 2, 2022

+1

@BenRacicot
Copy link

I have to be that guy 😂 first to bump this in 2023!

@SatarisGIT
Copy link

... and next bump :P

@ghaschel
Copy link

ghaschel commented Apr 4, 2023

And here it goes another one

@haskelcurry
Copy link

haskelcurry commented Apr 5, 2023

They are too busy with Signals or other useless cr@p, guys

@n614cd
Copy link

n614cd commented Apr 27, 2023

I also ran into one of the use cases listed above. That is with the Angular material components. The only workaround ends up being the replication of extensive amounts of boiler plate code in HTML.

@j-a-m-l
Copy link

j-a-m-l commented Jun 27, 2023

I just want to point out that maybe some of you could try angular/components#9411 (comment).

I'm grateful to @GrandSchtroumpf for its workaround.

@csisy-bt4w
Copy link

Another stackblitz for a simple use-case, where the content of a child component is queried via a directive but the content is provided through a parent: https://stackblitz.com/edit/stackblitz-starters-fndspl?file=src%2Fmain.ts

@ngaritagoitia
Copy link

bump again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: core Issues related to the framework runtime core: content projection core: queries feature Issue that requests a new feature needs: discussion Indicates than an issue is an open discussion type: use-case
Projects
None yet
Development

No branches or pull requests