$attrs.$observe in modern Angular
$attrs.$observe existed to follow an interpolated attribute. In Angular the attribute is an input signal, and host bindings write its value back to the element.
Before · AngularJS
app.directive('tooltip', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
attrs.$observe('tooltip', function (text) {
element.attr('title', text);
element.attr('aria-label', text);
});
}
};
});
<button tooltip="Delete {{ vm.user.name }}">x</button>After · Angular@Directive({
selector: '[appTooltip]',
host: {
'[attr.title]': 'text()',
'[attr.aria-label]': 'text()',
},
})
export class TooltipDirective {
text = input.required<string>({ alias: 'appTooltip' });
}
<button appTooltip="Delete {{ user().name }}">x</button>What changes
- The observed attribute becomes input(); an alias lets the input share the name of the directive selector.
- element.attr and attrs.$set calls become '[attr.name]' entries in the host object.
- Code that reacted inside the $observe callback becomes a computed or an effect that reads the input.
Migration tip. $observe callbacks often parsed strings such as 'true' or '10'. Move that parsing into the input transform (booleanAttribute, numberAttribute) so the rest of the class works with real types.
Related
- $scope.$emit
- nested ng-controller and scope inheritance
- ngMock unit tests (module, inject, $controller)
- isolate scope (scope: {})
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