Theory
એવાં components જેમને વાત કરવી પડે
FestConnect ના event ના LIST (parent) એ દરેક event નો data નીચે event ના CARD (child) સુધી પહોંચાડવો પડે છે, અને વપરાશકાર કોઈ card પર click કરે ત્યારે child એ ઉપર parent ને કહેવું પડે છે કે કયો event પસંદ થયો.
આ બંને દિશાની વાતચીત, એટલે કે નીચે data અને ઉપર events, એ જ component communication છે, અને Angular પાસે એના માટે બરાબર બંધબેસતી જોડી છે: @Input અને @Output. આ પાઠમાં એ બંને શીખશો, અને સાથે directives પણ: template ની એ ખાસ સૂચનાઓ (*ngFor, *ngIf, ngClass) જે elements ને પુનરાવર્તિત કરે છે, શરત પ્રમાણે બતાવે છે અને શણગારે છે. આ બધું તમને React ના props નીચે તથા callbacks ઉપર, અને map તથા શરતી rendering જેવું લાગતું હોય, તો એ ઓળખ જ તમારો ટૂંકો રસ્તો છે.
Theory
@Input down, @Output up
Angular ની communication એક બંધબેસતી જોડી છે:
- @Input() એવી property પર નિશાની કરે છે જેમાં PARENT data મોકલી શકે: data નીચેની દિશામાં વહે છે, બરાબર React ના props ની જેમ.
@Input() event: Event; - EventEmitter સાથેનું @Output() CHILD ને પોતાના parent સુધી ઉપર event મોકલવા દે છે. Child
this.selected.emit(this.event)કરે છે, અને parent(selected)="onSelect($event)"વડે સાંભળે છે
એટલે નિયમ સમતોલ છે: data નીચે લઈ જવા @Input, અને events ઉપર મોકલવા @Output. Child ક્યારેય parent ની અંદર હાથ નાખતું નથી; એ ફક્ત EMIT કરે છે, અને શું કરવું એ parent નક્કી કરે છે. દરેક દિશામાં એક જ તરફનો આ પ્રવાહ data ને અંદાજ બાંધી શકાય એવો રાખે છે, એટલે કે એ જ શિસ્ત જે React props અને callbacks વડે પળાવે છે.
Practical
Parent અને child વચ્ચેની વાતચીત
// CHILD component: @Input વડે data મેળવે છે, @Output વડે ઉપર મોકલે છે
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-event-card',
template: `
<div (click)="select()">{{ event.name }}</div>
`
})
export class EventCardComponent {
@Input() event: any; // parent તરફથી નીચે આવતો data
@Output() chosen = new EventEmitter<any>(); // parent સુધી ઉપર જતો event
select() {
this.chosen.emit(this.event); // parent ને જાણ કરો
}
}
// PARENT નું template એને વાપરે છે: અંદર data મોકલે, બહાર આવતો event સાંભળે
// <app-event-card [event]="ev" (chosen)="onChosen($event)"></app-event-card>
Theory
Directives: structural સામે attribute
Directives એટલે templates માં તમે મૂકતી સૂચનાઓ. એના બે પ્રકાર છે:
Structural directives DOM ની રચના બદલે છે (elements ઉમેરે કે કાઢે છે), અને એમની આગળ * લાગે છે:
*ngIf="seats > 0": શરત સાચી હોય તો જ element ને render કરે છે*ngFor="let ev of events": યાદીના દરેક ઘટક માટે element ને પુનરાવર્તિત કરે છે*ngSwitch: અનેક cases માંથી એક પસંદ કરે છે
Attribute directives element ને ઉમેર્યા કે કાઢ્યા વગર જ એનો દેખાવ કે વર્તન બદલે છે:
[ngClass]="{ soldout: seats === 0 }": શરત પ્રમાણે CSS class ઉમેરે કે કાઢે છે[ngStyle]="{ color: seats > 0 ? 'green' : 'red' }": inline styles ગોઠવે છે
ભેદ આ રહ્યો: structural (*) બદલે છે કે કયાં elements હયાત છે; જ્યારે attribute બદલે છે કે હયાત elements કેવાં દેખાય છે.
Quiz
Angular માં CHILD component પોતાના PARENT સુધી ઉપર data કે event કઈ રીતે મોકલે છે?
- @Input() વડે
- @Output() અને EventEmitter વડે: child emit કરે છે, અને parent (event)="handler($event)" વડે સાંભળે છે
- Parent ની properties સીધી બદલી નાખીને
- એ મોકલી શકતું જ નથી; data ફક્ત નીચેની દિશામાં જ વહે છે
Show the answer
@Output() અને EventEmitter વડે: child emit કરે છે, અને parent (event)="handler($event)" વડે સાંભળે છે
Child EventEmitter સાથેના @Output() વડે ઉપર events મોકલે છે: એ @Output() chosen = new EventEmitter() જાહેર કરે છે, કશું બને ત્યારે this.chosen.emit(value) બોલાવે છે, અને parent template માં (chosen)="onChosen($event)" વડે એની સાથે જોડાય છે. @Input() (વિકલ્પ A) તો ઊલટી દિશા છે: parent થી child તરફ નીચે વહેતો data. વિકલ્પ C Angular ની રચનાનો ભંગ કરે છે: child ક્યારેય પોતાના parent માં સીધો હાથ નાખતું નથી; એ emit કરે છે અને જવાબ આપવાનું parent પર છોડે છે (જેથી data નો પ્રવાહ અંદાજ બાંધી શકાય એવો રહે). વિકલ્પ D @Input પૂરતો અડધો સાચો છે, પણ @Output ને અવગણે છે, જે તો ઉપર events મોકલવા માટે જ છે. જોડી આ રહી: @Input નીચે, @Output ઉપર, જે React ના props નીચે અને callbacks ઉપર વાળા ઢાંચાનું જ પ્રતિબિંબ છે.
Think first
Angular નાં directives ને React ના ઢાંચા સાથે મેળવો
React માં (Unit 2) તમે યાદી માટે {items.map(...)} અને શરત માટે {cond && <X/>} વાપરતા હતા. Angular માં એનાં સમકક્ષ કયાં છે, અને એ પરથી શું સમજાય છે? વિચારીને પછી tap કરો.
Show the answer
યાદી render કરવા માટેનું React નું {items.map(item => <X/>)} એટલે Angular નું ngFor="let item of items". શરત પ્રમાણે બતાવવા માટેનું React નું {condition && <X/>} (કે ternary) એટલે Angular નું ngIf="condition". અને React ની className કે style વાળી logic Angular ના [ngClass] તથા [ngStyle] સાથે બંધબેસે છે.
એ પરથી સમજાય છે કે બંને frameworks template ની એ જ ત્રણ સમસ્યાઓ ઉકેલે છે, એટલે કે યાદીનું પુનરાવર્તન, શરત પ્રમાણે કશુંક બતાવવું, અને શરત પ્રમાણે શણગારવું, બસ syntax જુદો છે (JSX માં JavaScript ના expressions સામે Angular ના templates માં directives). એટલે Angular નાં directives શીખવાં એટલે મોટે ભાગે તો તમારી પાસે React થી પહેલેથી જ છે એવા ઢાંચાનાં નવાં નામ શીખવાં. બીજું framework પહેલા કરતાં ઝડપથી શીખાય છે એનું કારણ આ જ છે: ખ્યાલો સાથે આવે છે, ફક્ત જોડણી બદલાય છે.
Watch out
Communication અને directives ની ભૂલો
ખોટી દિશા: @Input નીચે જાય છે (parent થી child), અને @Output કે EventEmitter ઉપર જાય છે (child થી parent); બંનેને અદલાબદલી ન કરો.
*Structural directives પરનો ભૂલી જવો*: એ ngIf અને *ngFor છે (તારો અગત્યનો છે); [ngClass] તથા [ngStyle] માં કૌંસ વપરાય છે, તારો નહીં.
Child એ parent ને સીધું બદલવું: એને બદલે event emit કરો; data નો પ્રવાહ એક જ દિશાનો રાખો.
ngFor માં 'let' રહી જવું: એ ngFor="let ev of events" છે, ngFor="ev of events" નહીં.
Structural અને attribute ને ગૂંચવવાં: structural (*) elements ઉમેરે કે કાઢે છે; attribute (ngClass/ngStyle) હયાત elements ને ફરી શણગારે છે.
Theory
Directives વપરાયાં; હવે પોતાનાં directives અને binding
હવે તમે components ને એકબીજા સાથે જોડી શકો છો અને templates ને ઘાટ આપવા Angular નાં built-in directives વાપરી શકો છો. હવે પછી: CUSTOM directives (તમારાં પોતાનાં લખવાં) અને DATA BINDING નું આખું ચિત્ર, એટલે કે interpolation, property binding, event binding, અને ngModel વાળું પેલું જાણીતું TWO-WAY binding જે form ના field અને variable ને પૂરેપૂરાં sync માં રાખે છે. Binding એ જ રીત છે જેનાથી Angular ના templates અને TypeScript એકબીજા સાથે વાત કરે છે.
Summary
Key takeaways
- Component communication: @Input() data ને નીચે પહોંચાડે છે (parent થી child, props ની જેમ); EventEmitter સાથેનું @Output() events ને ઉપર મોકલે છે (child થી parent).
- Child emit કરે છે (this.event.emit(value)); parent (event)="handler($event)" વડે સાંભળે છે.
- Directives એટલે template ની સૂચનાઓ; એના બે પ્રકાર: structural અને attribute.
- Structural directives (આગળ ) DOM ની રચના બદલે છે: ngIf (શરતી), ngFor='let x of list' (પુનરાવર્તન), ngSwitch.
- Attribute directives elements ઉમેર્યા કે કાઢ્યા વગર દેખાવ બદલે છે: ngClass (classes), ngStyle (inline styles).
- React સાથે મેળ: ngFor એટલે map, ngIf એટલે શરતી rendering, અને ngClass/ngStyle એટલે className/style.
- યાદ રાખવાની કડી: @Input નીચે, @Output ઉપર; તારાવાળાં directives ઉમેરે કે કાઢે, attribute directives ફરી શણગારે.