Description
Which @angular/* package(s) are relevant/related to the feature request?
No response
Description
Angular currently allows components to extend other classes for logic reuse, but it does not provide a mechanism to inherit or wrap templates from abstract base classes. This results in unnecessary redundancy and boilerplate when UI elements (such as shared buttons, headers, or layouts) are repeated across multiple components.
Developers are often forced to use wrapper components or repeat common markup, which increases complexity and maintenance overhead.
Use Case
Suppose you have multiple components that need to include the same "Save" and "Cancel" buttons. Currently, you must:
- Manually add these buttons to every child component’s template.
- Or wrap each component in a separate reusable component, which introduces another layer and forces you to create redurance component.
Instead, with template inheritance, these buttons could be declared once in a abstract base class template, and child components would automatically be rendered within that base structure, similar to how class inheritance works in TypeScript.
Proposed solution
Introduce a new Angular feature allowing template inheritance via an abstract component base class and a special projection tag (e.g., ).
Mechanics:
- Abstract Base Component: Defines a template with shared structure (e.g., layout, footer buttons).
- Child Component: Extends the base class and defines its specific content.
- Angular automatically wraps the child component’s template into the slot within the base component’s template at render time.
Example:
@Component({
selector: 'app-user-form',
template: `
<form>
<input placeholder="User Name" />
</form>
`
})
export class UserFormComponent extends BaseFormComponent {}
@Component({
template: `
<div class="form-wrapper">
<ng-extend></ng-extend>
<div class="actions">
<button>Save</button>
<button>Cancel</button>
</div>
</div>
`
})
export abstract class BaseFormComponent {}
Expected Rendered Output when just using <app-user-form/>
:
<div class="form-wrapper">
<form>
<input placeholder="User Name" />
</form>
<div class="actions">
<button>Save</button>
<button>Cancel</button>
</div>
</div>
Alternatives considered
- Wrapper Components