jQuery / angular.element in directives en Angular moderno
La mayoría de las llamadas a jQuery en una directiva cambiaban clases, estilos o listeners. Eso pasa a ser bindings en el template y en el objeto host, manejados por signals.
Antes · AngularJS
app.directive('expandable', function () {
return {
restrict: 'A',
link: function (scope, element) {
var body = element.find('.body');
var toggle = element.find('.toggle');
toggle.on('click', function () {
body.slideToggle();
element.toggleClass('open');
});
scope.$on('$destroy', function () { toggle.off('click'); });
}
};
});Después · Angular@Component({
selector: 'app-expandable',
host: { '[class.open]': 'open()' },
template: `
<button (click)="open.set(!open())">Toggle</button>
<div #body [style.max-height.px]="open() ? height() : 0"><ng-content /></div>
`,
})
export class ExpandableComponent {
open = signal(false);
height = signal(0);
body = viewChild.required<ElementRef<HTMLElement>>('body');
constructor() {
afterNextRender(() => this.height.set(this.body().nativeElement.scrollHeight));
}
}Qué cambia
- find(...).on('click') pasa a ser un binding de evento en el template, que Angular quita cuando se destruye el componente.
- toggleClass, css y attr pasan a ser bindings de clase, estilo y atributo; las animaciones como slideToggle pasan a ser transiciones CSS.
- Cuando el código necesita el elemento real, para medirlo o para entregárselo a una librería, obtenlo con viewChild y léelo dentro de afterNextRender; usa Renderer2 para cambiar elementos fuera de tu template.
Consejo de migración. Clasifica cada llamada a jQuery antes de reescribir: los cambios de estado pasan a ser bindings, las mediciones y el foco usan viewChild, y cada plugin necesita su propia decisión. El primer grupo es el más grande y desaparece dentro del template.
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