require (parent controllers) en Angular moderno
require: '^^parent' pasa a ser inject(ParentComponent). Angular busca al padre hacia arriba en el árbol de elementos, igual que lo hacía require.
Antes · AngularJS
app.component('tabPane', {
require: { tabs: '^^tabGroup' },
bindings: { title: '@' },
transclude: true,
template: '<div ng-show="$ctrl.active" ng-transclude></div>',
controller: function () {
this.$onInit = function () { this.tabs.addPane(this); };
this.$onDestroy = function () { this.tabs.removePane(this); };
}
});Después · Angular@Component({
selector: 'app-tab-pane',
template: `<div [hidden]="!active()"><ng-content /></div>`,
})
export class TabPaneComponent {
private tabs = inject(TabGroupComponent);
title = input.required<string>();
active = computed(() => this.tabs.selected() === this);
}
// in TabGroupComponent: the parent finds its panes with a query
panes = contentChildren(TabPaneComponent);
selected = signal<TabPaneComponent | undefined>(undefined);Qué cambia
- Un require opcional ('?^^parent') pasa a ser inject(ParentComponent, { optional: true }).
- Los hijos ya no se registran con addPane y removePane: el padre los lee con contentChildren o viewChildren.
- Cuando los dos componentes no son ancestro y descendiente, usa un servicio declarado en los providers de su contenedor común.
Consejo de migración. Un padre y un hijo que referencian la clase del otro desde archivos separados crean un import circular. Deja el par en un solo archivo, o haz que el hijo inyecte un InjectionToken que el padre provee.
Relacionado
¿Planeas una migración o una plataforma de microfrontends?
En una llamada de 20 minutos me cuentas tu situación y te digo cómo la abordaría. Si todavía no vale la pena, también te lo digo.
Escríbeme por LinkedIn