Angular @Input @Output
Parent HTML:
<div style="border: 1px solid green; padding: 10px;">
<h2>Home Component</h2>
<p>Routing message: {{ (routeData$ | async)?.message }}</p>
<button (click)="increase()">Increase</button>
<app-contact-us [phoneNumber]="myPhone.toString()" mainOffice="something" [initialEmployeeCount]="homeEmployeeCount"
(onEmployeeCountChanged)="handleEmployeeCountChanged($event)"></app-contact-us>
<hr />
Parent employee count: {{homeEmployeeCount}}
<br/>
</div>
Parent TypeScript:
import { AsyncPipe, JsonPipe } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { map, Observable, tap } from 'rxjs';
import { ContactUs } from './contact-us/contact-us';
import { HomeResolverData } from '../../resolvers/home.resolver';
@Component({
selector: 'app-home',
imports: [AsyncPipe, ContactUs],
templateUrl: './home.html',
styles: ``,
})
export class Home implements OnInit {
/**
*
*/
myPhone = 1314;
homeEmployeeCount = 7;
routeData$!: Observable<HomeResolverData>;
constructor(private route: ActivatedRoute) {
// console.log(JSON.stringify(this.route.data));
// console.log(this.routeData$);
}
ngOnInit(): void {
this.routeData$ = this.route.data.pipe(
map((resolved) => resolved['homeResolver'] as HomeResolverData),
tap((data) =>
console.log(
'RESOLVER_DATA_CONSUMED: Resolver data is now available in component:',
data
)
)
);
}
increase() {
++this.myPhone;
}
handleEmployeeCountChanged($event: number) {
this.homeEmployeeCount = $event;
}
}
Child HTML:
<div>
<h4>Contact Us</h4>
Phone: {{phoneNumber}}<br/>
Main Office: {{primaryOffice}}<br/>
<button (click)="welcomeEmployee()">Welcome employee</button>
</div>
Child TypeScript:
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-contact-us',
imports: [],
templateUrl: './contact-us.html',
styles: ``
})
export class ContactUs {
@Input() phoneNumber = '';
@Input('mainOffice') primaryOffice!: string;
@Input() initialEmployeeCount = 0;
@Output() onEmployeeCountChanged = new EventEmitter<number>();
welcomeEmployee() {
++this.initialEmployeeCount;
this.onEmployeeCountChanged.emit(this.initialEmployeeCount);
}
}
React
Parent HTML+TypeScript:
import { useLoaderData } from "react-router";
import { ContactUs } from "./Home/ContactUs";
import { useState } from "react";
export default function Home() {
const homeData = useLoaderData();
const [myPhone, setMyPhone] = useState(1314);
const [homeEmployeeCount, setHomeEmployeeCount] = useState(7);
return (
<>
<h2>Home Component</h2>
<p>Routing message: {homeData.message}</p>
<button onClick={increase}>Increase</button>
<ContactUs
phoneNumber={myPhone.toString()}
mainOffice="something"
initialEmployeeCount={homeEmployeeCount}
onEmployeeCountChanged={handleEmployeeCountChanged}
/>
<hr />
<button onClick={batchIncreaseFlawed}>Batch Increase Flawed</button>
<button onClick={batchIncreaseCorrect}>
Batch Increase Correct
</button>
<hr />
Parent employee count: {homeEmployeeCount}
</>
);
function handleEmployeeCountChanged(newCount: number) {
setHomeEmployeeCount(newCount);
}
function batchIncreaseFlawed() {
setMyPhone(myPhone + 1);
setMyPhone(myPhone + 1);
setMyPhone(myPhone + 1);
}
function batchIncreaseCorrect() {
setMyPhone((prev) => prev + 1);
setMyPhone((prev) => prev + 1);
setMyPhone((prev) => prev + 1);
}
function increase() {
setMyPhone((prev) => prev + 1);
}
}
Child HTML+TypeScript:
import { useState } from "react";
type Params = {
phoneNumber: string;
mainOffice: string;
initialEmployeeCount: number;
onEmployeeCountChanged: (newCount: number) => void;
};
export function ContactUs({
phoneNumber,
mainOffice: primaryOffice,
initialEmployeeCount,
onEmployeeCountChanged,
}: Params) {
const [employeeCount, setEmployeeCount] = useState(initialEmployeeCount);
return (
<div>
<h4>Contact Us</h4>
Phone: {phoneNumber} <br />
Main Office: {primaryOffice}<br />
<button onClick={welcomeEmployee}>Welcome employee</button>
</div>
);
function welcomeEmployee() {
setEmployeeCount((prev) => prev + 1);
onEmployeeCountChanged(employeeCount);
}
}
Angular: @Input @Output ◆ React's Angular @Input @Output
No comments:
Post a Comment