nested ng-controller and scope inheritance in modern Angular
Nested controllers shared data through scope inheritance. Components share nothing implicitly: the parent passes each value to the child through an input.
Before · AngularJS
<div ng-controller="OrderCtrl">
<h2>{{ order.number }}</h2>
<div ng-controller="LinesCtrl">
<!-- order comes from the parent scope -->
<p ng-repeat="line in order.lines">{{ line.sku }}</p>
<!-- writes to the child scope only -->
<input ng-model="filter">
</div>
</div>After · Angular@Component({
selector: 'app-order',
imports: [OrderLinesComponent],
template: `
<h2>{{ order().number }}</h2>
<app-order-lines [lines]="order().lines" [(filter)]="filter" />
`,
})
export class OrderComponent {
order = input.required<Order>();
filter = signal('');
}
// OrderLinesComponent
lines = input.required<Line[]>();
filter = model('');What changes
- A child template cannot read parent properties; every value it needs is declared as an input.
- The shadowing problem, where writing a primitive in a child scope silently created a copy, disappears; use model() when the child must write back.
- $parent references become inputs, outputs or an injected service.
Migration tip. Convert the controllers to controllerAs syntax before migrating. Every reference then carries a prefix, and the names that belong to an outer controller become the input list of the new child component.
Related
Planning a migration or a micro-frontend platform?
In a 20-minute call you describe your situation and I tell you how I'd approach it. If it isn't worth doing yet, I'll say so.
Message me on LinkedIn