liveBook · Manning

Output property

As explained in Pro Angular 16

An output property is a directive or component property that exposes an event through which it can emit values to its parent template.

An output property lets an Angular directive or component expose a custom event to its parent template. Declare it with @Output and connect it to an EventEmitter; calling emit sends a value to listeners. The emitted value may be a string, number, data-model object, or JavaScript Event object. section 14.4 section 16.5

Use an output property to:

  • Translate a host DOM event into an application-specific event, such as emitting a product category after a row is clicked. section 14.4
  • Choose the template-facing event name with the @Output alias and pass the payload through emit(value). section 14.4
  • Pair an input property with a change event to create a two-way binding, including the [(paModel)] shorthand. section 14.6
  • Test emitted values by subscribing to the EventEmitter and triggering the originating interaction directly or through host events. section 29.4.5

Directive event and template listener

A directive can expose @Output("pa-category") click = new EventEmitter<string>();. After its host click, it calls this.click.emit(this.product.category). A parent template listens with (pa-category)="newProduct.category = $event", receiving the emitted category as $event.

Output-driven two-way binding

The PaModel directive emits a new input value from @HostListener("input", ["$event.target.value"]). Its @Output("paModelChange") update = new EventEmitter<string>() sends the value, allowing [paModel] and (paModelChange) to collapse into [(paModel)].

Listing 14.15. Defining an output property in the attr.directive.ts file in the src/app folder
import { Directive, ElementRef, Input, SimpleChanges, Output, EventEmitter } 
    from "@angular/core";
import { Product } from "./product.model";

@Directive({
    selector: "[pa-attr]"
})
export class PaAttrDirective {

    constructor(private element: ElementRef) {
        this.element.nativeElement.addEventListener("click", () => {
            if (this.product != null) {
                this.click.emit(this.product.category);
            }
        });
    }

    @Input("pa-attr")
    bgClass: string | null = "";

    @Input({ required: true, alias: "fg-class"})
    fgClass: string | undefined;

    @Input("pa-product")
    product: Product = new Product();

    @Output("pa-category")
    click = new EventEmitter<string>();

    ngOnChanges(changes: SimpleChanges) {
        ["bgClass", "fgClass"].forEach(c => {
            let change = changes[c];
            if (change) {
                let classList = this.element.nativeElement.classList;
                if (!change.isFirstChange() && 
                        classList.contains(change.previousValue)) {
                    classList.remove(change.previousValue);
                }
                if (!classList.contains(change.currentValue)) {
                    classList.add(change.currentValue);
                }
            }
        });
    }
}

Inspect the complete directive listing to see imports, input properties, the aliased output property, host-event handling, and emitted payload together. section 14.4

How Pro Angular 16 covers it

How deep it goes
Explains @Output aliases, EventEmitter payloads, emit calls, host-event wiring, two-way binding, and subscription-based tests.
Examples
Uses clickable product rows, a paModel input, host input events, component highlighting, and parent-template assignments as concrete examples.
What it assumes
Assumes familiarity with Angular templates, directives or components, DOM events, and property binding while refreshing output-property mechanics.
What you can do after
Build it from scratch, wire emitted values into parent templates, implement two-way directive bindings, and test output events through subscriptions.
How it connects
Ties output properties to custom events, input properties, host listeners, two-way binding, components, directives, EventEmitter, and unit testing.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Pro Angular 16. The section links point to the parts of the book it draws on.