Angular 22
Ejercicios de Angular sobre Componentes
8 ejercicios de Componentes en Angular. Piensa la respuesta antes de abrirla: la explicación dice por qué las demás opciones fallan.
1 · Elige la respuesta · nivel 1
¿Cómo escucha el componente padre el evento closed?
@Component({ selector: 'app-dialog', template: `...` })export class Dialog { closed = output<void>(); close() { this.closed.emit(); }}- A<app-dialog (closed)="onClosed()" />
- B<app-dialog [closed]="onClosed()" />
- C<app-dialog closed="onClosed()" />
- D<app-dialog (closed.emit)="onClosed()" />
Ver la respuesta
Respuesta: A. <app-dialog (closed)="onClosed()" />
output() declara un evento del componente. El padre lo escucha con paréntesis, igual que un click. Los corchetes son para las entradas.
2 · Elige la respuesta · nivel 1
¿Qué decorador convierte una clase en un componente de Angular?
@___({ selector: 'app-header', template: '<h1>Mi web</h1>',})export class Header {}- A@Component
- B@Injectable
- C@NgModule
- D@Directive
Ver la respuesta
Respuesta: A. @Component
@Component marca la clase como componente y recibe su configuración: el selector, la plantilla y los estilos. @Injectable es para servicios.
3 · Elige la respuesta · nivel 1
Un componente tiene selector: 'app-card'. ¿Cómo se usa en la plantilla de otro componente (que lo tiene en imports)?
- A<app-card />
- B<Card />
- C{{ app-card }}
- D<component name="app-card" />
Ver la respuesta
Respuesta: A. <app-card />
El selector es el nombre de la etiqueta con la que se usa el componente. Además, el componente padre tiene que tenerlo en su lista de imports.
4 · Ordena las líneas · nivel 1
Ordena un componente que muestre Hola.
- selector: 'app-hello',
- template: '<p>Hola</p>',
- template: <p>Hola</p>,
- })
- @Component({
- export class Hello {}
Ver la respuesta
El orden correcto:
@Component({ selector: 'app-hello', template: '<p>Hola</p>',})export class Hello {}Sobran: template: <p>Hola</p>,
El decorador @Component va justo encima de la clase y recibe un objeto con el selector y la plantilla. La plantilla es un string, así que va entre comillas.
5 · Elige la respuesta · nivel 2
¿Cómo se usa este componente desde otra plantilla?
@Component({ selector: 'app-badge', template: `<span>{{ label() }}</span>`,})export class Badge { label = input.required<string>();}- A<app-badge label="Nuevo" />
- B<app-badge (label)="Nuevo" />
- C<app-badge label()="Nuevo" />
- D<app-badge />
Ver la respuesta
Respuesta: A. <app-badge label="Nuevo" />
input() declara una entrada basada en signals y se asigna como cualquier atributo o con [label]. Al ser required, omitirlo es un error de compilación. Los paréntesis son para salidas (eventos).
6 · Encuentra el fallo · nivel 2
El componente tiene que poder cambiar su propia valoración, pero no compila: Property 'set' does not exist. ¿Qué línea hay que cambiar?
1export class Rating {2 value = input(0);3 4 rate(stars: number) {5 this.value.set(stars);6 }7}Ver la respuesta
El fallo está en la línea 2:
value = input(0);Una entrada creada con input() es de solo lectura dentro del componente. Si el hijo también tiene que cambiar el valor, se declara con model(0), y el padre recibe el cambio con [(value)].
7 · Completa el hueco · nivel 2
Completa para añadir la clase active al propio elemento del componente y escuchar sus clics.
@Component({ selector: 'app-chip', ___: { '[class.active]': 'active()', '(click)': 'toggle()' }, template: '<ng-content />',})export class Chip { active = signal(false); toggle() { this.active.update((v) => !v); }}- host
- hostBindings
- attrs
- @HostBinding
- providers
- bindings
Ver la respuesta
Respuesta: host
@Component({ selector: 'app-chip', host: { '[class.active]': 'active()', '(click)': 'toggle()' }, template: '<ng-content />',})export class Chip { active = signal(false); toggle() { this.active.update((v) => !v); }}La propiedad host del decorador enlaza propiedades, clases y eventos del elemento anfitrión, <app-chip>. Es la forma recomendada frente a los decoradores @HostBinding y @HostListener.
8 · Ordena las líneas · nivel 2
Ordena un componente standalone que salude con una entrada opcional name.
- name = input('mundo');
- selector: 'app-hello',
- standalone: false,
- template: `<h1>Hola, {{ name() }}</h1>`,
- }
- })
- @Component({
- export class Hello {
Ver la respuesta
El orden correcto:
@Component({ selector: 'app-hello', template: `<h1>Hola, {{ name() }}</h1>`,})export class Hello { name = input('mundo');}Sobran: standalone: false,
Los componentes son standalone por defecto, así que no hace falta declararlo. input('mundo') crea una entrada opcional con valor por defecto.