8000 Support Input/Output spread · Issue #14545 · angular/angular · GitHub
[go: up one dir, main page]

Skip to content

Support Input/Output spread #14545

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

Open
jiayihu opened this issue Feb 16, 2017 · 28 comments
Open

Support Input/Output spread #14545

jiayihu opened this issue Feb 16, 2017 · 28 comments
Labels
area: core Issues related to the framework runtime core: inputs / outputs feature: under consideration Feature request for which voting has completed and the request is now under consideration feature Issue that requests a new feature
Milestone

Comments

@jiayihu
Copy link
jiayihu commented Feb 16, 2017

I'm submitting a ... (check one with "x")

[ ] bug report => search github for a similar issue or PR before submitting
[x] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

Currently each Input or Output must be explicitly declared in the component to allow its usage.

Expected behavior

I'd like to have any way to pass Inputs/Outputs to a component in the template without declaring them first. This is allowed in React with props spread and allows techniques like Higher Order Components.

<my-component [prop1]="prop1" {...otherInputs} ></my-component>

What is the motivation / use case for changing the behavior?

Declaring each Input/Output is a problem when wrapping some component to extend its behaviour or to hide the component when dealing with an external library. It requires mapping each of the wrapped component Inputs/Outputs and it's very tedious and error prone. Besides any change in the wrapped component API would require touching the wrapper component.

@lacolaco
Copy link
Contributor

related to #11850

@DzmitryShylovich
Copy link
Contributor

Don't think they are related. This is a much more complex feature.

@jiayihu
Copy link
Author
jiayihu commented Feb 17, 2017

@laco0416 yup not much related. That issue asks for array spread in function calls, whereas this feature is more object spread of Inputs/Outputs.

@otodockal
Copy link
Contributor

@fabiobiondi @manuel-di-iorio sorry guys, but don't spam the thread with "+1", use reactions instead.

@fabiobiondi
Copy link
fabiobiondi commented Feb 20, 2017

Sorry otodockal I was on mobile phone and it didn't support reactions. Now fixed 8000 . Thanx

@tbosch tbosch added area: core Issues related to the framework runtime feature Issue that requests a new feature labels Apr 10, 2017
@crysislinux
Copy link

any updates on this? It's really verbose when you want to wrap some components. for example, if you want to use mat-select from @angular/material but apply some additional styles on it to make it another component(logically). It's not ideal to add a directive on it because:

  1. it seems more readable to use a single component rather than add the directive every time
  2. sometimes you just want wrap mat-select and add styles on the wrapper instead of change the style of mat-select
  3. sometimes it's just impossible to implement all the stuff without adding new wrapper dom elements.

Higher Order Components solves this problem quite well. I cannot figure out another way to do the same thing without write all the Input on the wrapper again. When dealing with Output, it's even verbose because you have to introduce EventEmitter for each Output again.

@YogliB
Copy link
YogliB commented Aug 12, 2020

any chance we'll see this anytime?

@pacocom
Copy link
pacocom commented Nov 20, 2020

I like spead props! In React is possible!!
Please add this to Angular.

@LinboLen
Copy link
LinboLen commented Dec 23, 2020

like this?

<my-component [prop1]="prop1" [...otherInputs] (...otherOutputs) ></my-component>

or maybe

<my-component [prop1]="prop1" [...]="otherInputs" (...)="otherOutputs" ></my-component>

@mlc-mlapis
Copy link
Contributor

@shybaLen What such a syntax means concretely on the <my-component> side? And what otherInputs and otherOutputs means on the host side?

@angular-robot angular-robot bot added the feature: under consideration Feature request for which voting has completed and the request is now under consideration label Jun 4, 2021
@petebacondarwin
Copy link
Contributor

This is being tracked in the aggregate issue of #43485 for which we need to create a project proposal.

@victor-assis
Copy link

hi, I created a possible one just for this case, I named it ngAttribute, it is a directive that receives all the input that must be included in the host, it has the same logic as the host in the directive/component decorator

stackblitz: https://stackblitz.com/edit/angular-ivy-mvhptb?file=src%2Fapp%2Fdirectives%2Fng_attribute.ts

@ghost
Copy link
ghost commented Aug 24, 2022

Maybe a new directive and decorator could be implemented:
HTML (parent):

<my-component [prop1]="prop1" [ngProp]="otherInputs" [ngOn]="otherOutputs"></my-component>

HTML (my-component):

<input [prop1]="prop1" [ngProp]="otherInputs" [ngOn]="otherOutputs">

Component (my-component):

//...
class MyComponent {
    @SpreadInputs() otherInputs: Record<string, any>
    @SpreadOutputs() otherOutputs: Record<string, EventEmitter<any>> = {}
}

@gund
Copy link
gund commented Sep 9, 2022

@IRod22 this directives already exists for inputs and outputs for dynamic components in ng-dynamic-component, the thing is it is currently only applicable to a dynamically rendered component and not statically rendered one but it should be quite easy to add support to a static components too.

@ghost
Copy link
ghost commented Oct 3, 2022

@gund that is a good idea, but I think the community would want built-in decorators/directives instead of having verbose syntax and extra NgModule imports; mainly for ergonomics, Angular's learning curve, and security reasons. Vue has spread-props via v-bind and specific props with v-bind:prop/:prop, so why could the same not be baked into Angular?

We may need an RFC or at least a poll for this as it is a potential breaking change.

@pkozlowski-opensource
Copy link
Member

Related: #41993

@b-barry
Copy link
b-barry commented Apr 12, 2023

Hello all,

Do we have a workaround at the moment?

@xc404
Copy link
xc404 commented May 25, 2023

I'm waiting for this feature

@tombohub
Copy link

I believe this feature made react what is today. Because it's so easy to extend and build upon something. Just compare number of component libraries in react compared to other frameworks. We people are lazy, don't wanna type every single input to extend a component. This feature is of strategic importance for the benefit of angular ecosystem.

@otodockal
Copy link
Contributor

There is also a new library called Zag, which takes a novel approach to building UI components using FSMs(Finite State Machines) and heavily leverages spreads.
It would be a great addition to the Angular ecosystem if spreads is supported.
https://zagjs.com/

@tombohub
Copy link

@otodockal how come there is no svelte version of zagjs? does svelte makes it hard to implement?

@otodockal
Copy link
Contributor

@tombohub They gave it a try, but it was removed for some reason chakra-ui/zag@bdb1950
There seems to be a problem with the lack of support for Events. sveltejs/svelte#5112

@victor-assis
Copy link

Given this new feature, I was thinking, what if Angular had abstract directives that implement interfaces for native elements?
for example:

@Directive()
export abstract class HTMLInputElementDirective extends HTMLElementDirective {
  /** accumulates all inputs */
  protected hostInput: Partial<HTMLInputElement> = {};

  /** Sets or retrieves a comma-separated list of content types. */
  @Input()
  accept: string;

  @HostBinding('attr.accept')
  private acceptHost = null;

  /**
   * Sets or retrieves how the object is aligned with adjacent text.
   * @deprecated
   */
  @Input()
  align: string;

  @HostBinding('attr.align')
  private alignHost = null;

I created a complete example using a directive I created a while ago, which binds attributes:
https://stackblitz.com/edit/angular-ivy-mvhptb?file=src%2Fapp%2Fapp.component.html,src%2Fapp%2Fcomponents%2Fcheckbox%2Fcheckbox.component.ts

@MGREMY
Copy link
MGREMY commented Jan 25, 2024

Any update on this ? :)

@robinsjovoll
Copy link

Also wondering about this - any updates? It would really help when creating wrapper components around third party components for instance. So that when the third party updates their components we doesn't have to explicitly add or change the params in our wrapper to support them.

@ConteClaudioSalvatore
Copy link

hi, i was also wondering if this feature is still unplanned...

@iwnow
Copy link
iwnow commented May 9, 2024

need it

@xc404
Copy link
xc404 commented Feb 2, 2025

any update on this feature

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: inputs / outputs feature: under consideration Feature request for which voting has completed and the request is now under consideration feature Issue that requests a new feature
Projects
None yet
Development

No branches or pull requests

0