Es la manera en que transmitimos datos entre componetes, no olvidemos que cada componente deberia tener una unica resposabildad principio Solid

Inputs

son los property Binding y se utiliza para comunicar un componente padre con un hijo. En react seria equivalente a los props que se comunican entre componentes.

En el siguiente ejemplo la clase ProductMdComponent tiene como selector app-product-md

import { Input } from '@angular/core';
export class ProductMdComponent{
  @Input() product: Product;
}

Para poder utilizar se deben importar de @angular/core'y se asignaran a un variable donde esos datos se van a almacenar en memoria, Recordemos que al tiparlo los datos recibidos serán con la estructura de la interfaces Products

<app-product-md
        *ngFor="let product of products"
        [product]="product"
      >
</app-product-md>

Para recibir los datos del componente padre estamos iterando los datos con *ngFor y utilizamos la variable product declarada con @input como es un input este debe ser encerrado en []

Output

Son los Event Binding y a diferencia de los input se utilizan con () dentro de las etiquetas de HTML se utilizan como eventos. Y se relaciona mucho con los metodos de la clase que vamos a utilizar en el HTML.

<button (click)="addCart(product)">
        Agregar
</button>

En el ejemplo de addCart se esta asignando el evento click, en HTML es el mismo OnClick, como es un output se debe encerrar con () y como valor se esta asignando el método que creamos.

addCart(product: Product){
	console.log(product)
}

En este método esta recibiendo el valor product de tipo products, y al realizar la ejecución del evento imprime en consola el objeto.

Sin embargo para comunicar informacion desde un componente hijo a padre necesitamos utilizar el output de una manera mas especifica utilizando el @output importando de @angular/core' y utilizar un EventEmitter

export class ProductComponent {
  @Output() clickAddToCart = new EventEmitter<any>(); 
// (clickAddToCart)= eventHandler($event):function
  ...
}

Los EventEmmiter's pueden emitir un evento con un argumento que será recibido por el padre.

export class ProductComponent {
  @Output() clickAddToCart = new EventEmitter<any>();
  addToCart(){
    this.clickAddToCart.emit(this.product.id)
  }
}

Para hacer uso del output podemos llamar el evento desde paréntesis y asignarle un evento (clickAddToCart)="handler($event)":

//componete Padre
export class AppComponent {
 ...
  handleProductAddToCart(id: number) {
    console.log('product -> id', id);
  }
}

// Template del componente padre
<app-product
  (clickAddToCart)="handleProductAddToCart($event)">
</app-product>

//El event es recibido desde el emit del EventEmmiter
this.clickAddToCart.emit(this.product.id)