-
Notifications
You must be signed in to change notification settings - Fork 233
Support component inheritance #231
Comments
Might I ask what is this blocked by? This would be a neat feature. |
We need to use resolved ASTs for codegen to enable this. The blocker is currently being worked on. |
Pushed to 4.0. We have all the work ready to support this, but are still testing this doesn't cause regressions or build performance issues so we don't want to block 3.0. Should be coming soon. |
This is now planned for the 4.0 release. |
If anyone would like to start an RFC on how this should work (or refer to TypeScript's implementation) that would be awesome. There is a chance this might slip from |
I would like to participate in this. |
We plan to support inheritance for all property annotations in 4.0.0.
Derived components will inherit their ancestor's property annotations, and may choose to override their implementations. If a derived component re-declares a named annotation on a different property, we'll treat this similarly to how duplicate annotations in a component currently behave. We won't be adding support for inheritance of class annotations yet.
|
Thank you for your support and interest @Lisenish. If you have any feedback on our current plans I'd be glad to hear it. If you feel strongly about inheritable class annotations, please feel to provide some details on how you'd like that to work. There's no one clear way to inherit class annotations. Since we haven't seen much demand for it yet, there's not much sense in committing to one arbitrary solution. |
I assume this just means annotations of sub and superclass aren't "merged", but need to repeated with all parameters on the subclass, right? |
It means the top-level class AComp {
@Input()
String a;
}
// Still has an @Input() for a.
class BComp extends AComp {} |
@leonsenft Good to hear, thanks! |
@Lisenish const baseProviders = const [...];
@Component(
selector: 'base',
templateUrl: 'base_component.html',
providers: baseProviders,
)
class BaseComponent {
...
}
@Component(
selector: 'derived',
templateUrl: 'base_component.html', // reuse supertype template URL
providers: baseProviders, // reuse supertype providers
)
class DerivedComponent extends BaseComponent {
...
} Yes, you still have to specify the My concern with your proposed solution is it's all or nothing. You either inherit the base metadata as-is, or replace it entirely. A solution where the derived component can interact in some way with its inherited metadata is much more compelling. Notice that all of the metadata we're initially supporting annotates a component method or property. Methods and property accessors can reference their inherited implementations via No parallel to this concept exists for annotation arguments. For example, a Just to be clear, we're not ruling out any particular implementation yet. We want to be sure that if and when we implement this, we get it right. I'd like to reiterate my earlier point that we just haven't seen much of a demand for inheritable templates/styles/providers and how particular implementations could solve problems in ways the framework currently struggles to. If you have a compelling example, we'd be happy to see a new issue with a detailed proposal. |
Polymer dropped template inheritance before 1.0 where the subclass can extend the template, because it was too complicated. |
@leonsenft Thanks for the detailed answer and clarification! |
Components now inherit the following metadata from their ancestor components * Host bindings * Host listeners * Inputs * Outputs * Queries * View queries Inheritance prohibits changing the binding names of inherited inputs and outputs. This ensures derived components preserve their inherited API, allowing seamless substitution of component subtypes. A consequence of this restriction, is that inheritance doesn't work well with a common directive pattern. It's typical for directives that rely on a primary input to use the same attribute for the input binding name and directive selector. If another directive were to inherit from such a directive, maintaining this pattern would require changing the inherited input binding name to match the derived directive's selector. As a result, inheritance of directives isn't supported yet. Progress towards #231. PiperOrigin-RevId: 160446534
Progress towards #231. PiperOrigin-RevId: 160465207
Components now inherit the following metadata from their ancestor components * Host bindings * Host listeners * Inputs * Outputs * Queries * View queries Inheritance prohibits changing the binding names of inherited inputs and outputs. This ensures derived components preserve their inherited API, allowing seamless substitution of component subtypes. A consequence of this restriction, is that inheritance doesn't work well with a common directive pattern. It's typical for directives that rely on a primary input to use the same attribute for the input binding name and directive selector. If another directive were to inherit from such a directive, maintaining this pattern would require changing the inherited input binding name to match the derived directive's selector. As a result, inheritance of directives isn't supported yet. Progress towards #231. PiperOrigin-RevId: 160446534
Progress towards #231. PiperOrigin-RevId: 160465207
@leonsenft your latest commits landed into master - do you want to mark this done? |
@matanlurey Not yet; only very limited support is landed. Currently components only support inheritance from ancestor components and directives. I have a pending change which extends inheritance to all ancestors, so you can annotate regular classes with metadata. |
…ering * If an inherited @input was declared on a field, a derived component could override the binding name on a setter. * If an inherited @input was declared on a setter, a derived component could declare a new binding name on a field which would silently fail. Progress on #231. PiperOrigin-RevId: 161823863
…ering * If an inherited @input was declared on a field, a derived component could override the binding name on a setter. * If an inherited @input was declared on a setter, a derived component could declare a new binding name on a field which would silently fail. Progress on #231. PiperOrigin-RevId: 161823863
Closes #231. PiperOrigin-RevId: 162000574
…g names Polishing #231. PiperOrigin-RevId: 162369805
…g names Polishing #231. PiperOrigin-RevId: 162369805
At current time Angular Dart doesn't support component hineritance of @component and @input and other metadata. This very important feature has been added in angular 2.3.0, are there any plan to support this in angular dart?
The text was updated successfully, but these errors were encountered: