Building Reusable UI Components & Design Patterns: reusable card, modal and alert components; component interaction with RxJS and Shared Services; ng-template, ng-container, ng-content; Smart vs Dumb Components

સારાં Angular apps ફરી વાપરી શકાય એવાં components માંથી બને છે: card, modal કે alert જે તમે એક વાર લખો અને બધે વાપરો, content projection થી લવચીક બનાવો, અને data લાવતાં smart components તથા ફક્ત બતાવતાં dumb components માં ગોઠવો.

11 min read · 8 cards · 2 checks

Read in: English · हिन्दी · ગુજરાતી


Theory

એક વાર લખો, બધે વાપરો

FestConnect events માટે cards બતાવે છે, કામની ખાતરી કરવા modals ખોલે છે, અને સંદેશા માટે alerts ઝબકાવે છે, અને એ પણ અનેક pages પર વારંવાર. એ markup દર વખતે નવેસરથી લખવું એ વેડફાટ પણ થાય અને એકસરખાપણું પણ ન રહે. Angular નો જવાબ છે ફરી વાપરી શકાય એવાં components: Card, Modal અને Alert એક વાર બનાવો, અને જ્યાં જરૂર પડે ત્યાં મૂકી દો.

આ પાઠ બતાવે છે કે content projection વડે components ને ખરેખર ફરી વાપરી શકાય એવાં કઈ રીતે બનાવવાં, અને smart તથા dumb ની રીતે એમને કઈ રીતે ગોઠવવાં. આ ટેવો વધતા જતા app ને એકસરખું અને સંભાળી શકાય એવું રાખે છે.

Theory

Content projection components ને લવચીક બનાવે છે

ફરી વાપરી શકાય એવું Card ત્યારે જ કામનું છે જ્યારે દરેક વાપરનાર એની અંદર જુદું લખાણ મૂકી શકે. એ જ સગવડ content projection આપે છે.

ng-content slot ની જેમ કામ કરે છે: વાપરનાર તમારા component ના tags ની અંદર જે markup મૂકે, એ template માં જ્યાં ng-content હોય ત્યાં ગોઠવાઈ જાય છે. એટલે એક જ CardComponent event ને, profile ને કે સંદેશાને લપેટી શકે છે, અને દરેક વાપરનાર અંદરનું લખાણ પોતે આપે છે. ng-template template નો એવો ટુકડો વ્યાખ્યાયિત કરે છે જે તમે વાપરવાનું નક્કી ન કરો ત્યાં સુધી render થતો નથી (modals અને શરત પ્રમાણેના લખાણ માટે કામનું), અને ng-container એવું અદૃશ્ય જૂથ બનાવતું element છે જે વધારાનું DOM ઉમેરતું નથી. આ ત્રણેય મળીને તમને લવચીક અને ફરી વાપરી શકાય એવાં UI નાં માળખાં બનાવવા દે છે.

Practical

ng-content (એટલે કે slot) વાપરીને ફરી વાપરી શકાય એવું Card

@Component({
  selector: 'app-card',
  standalone: true,
  template: `
    <div class="card">
      <ng-content></ng-content>   <!-- caller's markup is projected here -->
    </div>
  `,
})
export class CardComponent {}

// Usage: whatever you put inside <app-card> appears in the slot:
// <app-card><h3>Robotics Workshop</h3><p>Sat 10am</p></app-card>

Theory

Smart અને dumb components

એક કામની રીત components ને એમની જવાબદારી પ્રમાણે વહેંચે છે.

Smart (container) component data અને તર્ક વિશે જાણે છે: એ service પાસેથી events લાવે છે, state સાચવે છે, અને કામ સંભાળે છે. Dumb (presentational) component ને ફક્ત એટલી જ ખબર છે કે એને જે અપાયું છે એ કઈ રીતે બતાવવું: એ @Input દ્વારા data મેળવે છે અને @Output દ્વારા વપરાશકર્તાનાં કામ ઉપર જણાવે છે, અને data ક્યાંથી આવ્યો એની એને કશી ખબર હોતી નથી.

એટલે smart EventsPage events લાવે છે અને દરેકને બતાવવા માટે dumb EventCard ને આપે છે. Dumb components ખૂબ ફરી વાપરી શકાય એવાં હોય છે (એ કશી ધારણા બાંધતાં નથી) અને એમની ચકાસણી પણ સહેલી છે; smart components એમને app સાથે જોડે છે. દૂર દૂરનાં components વચ્ચે વાત કરવા માટે એ વહેંચાયેલી service માં RxJS દ્વારા state વહેંચે છે (જેમ કે હાલના વપરાશકર્તા માટે).

Practical

Dumb component: inputs અંદર, events બહાર

@Component({ selector: 'app-event-card', standalone: true,
  template: `<div (click)="select.emit(event)">{{ event.name }}</div>` })
export class EventCardComponent {
  @Input() event!: { name: string };     // data comes IN from the parent
  @Output() select = new EventEmitter();  // actions go OUT to the parent
}
// It knows nothing about services or where 'event' came from: pure display.
// A smart parent supplies [event]="..." and handles (select)="...".

Quiz

Smart અને dumb ની રીતમાં dumb (presentational) component ની ઓળખ શું છે?

  1. એ પોતાનો data services પાસેથી જાતે લાવે છે અને ધંધાકીય તર્ક સાચવે છે
  2. એ ફક્ત @Input દ્વારા મળેલો data બતાવે છે અને @Output દ્વારા events મોકલે છે, અને data ક્યાંથી આવે છે એની એને ખબર હોતી નથી
  3. એને ક્યાંય ફરી વાપરી શકાતું નથી
  4. એ TypeScript માં નહીં પણ સાદા JavaScript માં લખાય છે
Show the answer

એ ફક્ત @Input દ્વારા મળેલો data બતાવે છે અને @Output દ્વારા events મોકલે છે, અને data ક્યાંથી આવે છે એની એને ખબર હોતી નથી

Dumb (presentational) component ફક્ત @Input દ્વારા મળેલો data બતાવે છે અને @Output દ્વારા વપરાશકર્તાનાં કામ ઉપર જણાવે છે, અને data ક્યાંથી ઉદભવે છે એ જાણ્યા વગર જ કામ કરે છે, જેથી એ ખૂબ ફરી વાપરી શકાય એવું અને સહેલાઈથી ચકાસી શકાય એવું બને છે. વિકલ્પ A તો smart (container) component નું વર્ણન છે, જે services પાસેથી data લાવે છે અને તર્ક સાચવે છે. વિકલ્પ C સાવ ઊંધો છે: dumb components સૌથી વધુ ફરી વાપરી શકાય એવાં હોય છે, અને એનું કારણ જ એ છે કે એ data ના સ્રોત વિશે કશી ધારણા બાંધતાં નથી. વિકલ્પ D ખોટો છે: Angular નાં બધાં components TypeScript માં હોય છે. વહેંચણી જવાબદારી પ્રમાણે છે: smart components data અને તર્ક સંભાળે, dumb components બતાવવાનું સંભાળે.

Think first

Components ને smart અને dumb માં વહેંચવાની જરૂર જ શી છે?

દરેક component ને પોતાનો data જાતે લાવીને બતાવવા દઈએ તો શું વાંધો? Smart અને dumb ની વહેંચણીથી શું મળે છે? વિચારીને પછી tap કરો.

Show the answer

એનાથી ફરી વાપરવાની સગવડ, ચકાસવાની સરળતા અને સ્પષ્ટતા મળે છે, કારણ કે એ બે જુદી ચિંતાઓને છૂટી પાડે છે, એટલે કે data લાવવો અને data બતાવવો, અને એ બે જુદાં જુદાં કારણોસર બદલાતી હોય છે.

જે dumb component ફક્ત inputs લે અને outputs મોકલે, એ ગમે ત્યાં ફરી વાપરી શકાય છે, કારણ કે એ services, APIs કે app ની state વિશે કશી ધારણા બાંધતું નથી; એ જ EventCard database માંથી આવેલો event બતાવી શકે, search ના પરિણામમાંથી આવેલો બતાવી શકે, કે ચકાસણી માટે બનાવેલો બતાવી શકે, કારણ કે એને તો ફક્ત અંદર અપાયેલો event object જ જોઈએ છે. એથી એની ચકાસણી પણ સાવ સહેલી થઈ જાય છે: તમે એને થોડો data આપો અને જુઓ કે એ શું render કરે છે, અને એ માટે services કે network calls ના બનાવટી નમૂના બનાવવા પડતા નથી.

બીજી બાજુ, smart components ગૂંચવણવાળા ભાગ, એટલે કે data લાવવો, state સાચવવી અને જોડાણ કરવું, થોડી જ જગ્યાએ ભેગા કરે છે, જેથી app માં data નો પ્રવાહ સહેલાઈથી અનુસરી શકાય (data inputs દ્વારા નીચે આવે છે, events outputs દ્વારા ઉપર જાય છે).

એને બદલે જો દરેક component પોતાનો data જાતે લાવે, તો તમે API calls આખા UI માં વેરી નાખો, તર્કની નકલ કરો, components ને ફરી વાપરવાં અઘરાં બનાવો (દરેક કોઈ ચોક્કસ data ના સ્રોત સાથે બંધાયેલું હોય), અને ચકાસણી પણ કંટાળાજનક બનાવો (દરેક component માટે એની services ના બનાવટી નમૂના જોઈએ).

Smart અને dumb ની આ રીત ખરેખર તો component ના વૃક્ષ પર separation of concerns લગાડવાની જ વાત છે, એ જ સિદ્ધાંત જે તમે અગાઉ ઠેર ઠેર જોયો છે, અને એ મોટા Angular app ને વધતું જાય તો પણ સંભાળી શકાય એવું રાખે છે. થોડી smart જગ્યાએ data લાવો, અને ઘણાં ફરી વાપરી શકાય એવાં dumb components માં એને બતાવો.

Summary

Key takeaways

  • ફરી વાપરી શકાય એવાં components (Card, Modal, Alert) એક વાર લખાય છે અને એકસરખાપણા માટે આખા app માં વપરાય છે.
  • Content projection એમને લવચીક બનાવે છે: ng-content એ વાપરનારના markup માટેનું slot છે.
  • ng-template એવું template વ્યાખ્યાયિત કરે છે જે વપરાય નહીં ત્યાં સુધી render થતું નથી; ng-container વધારાનું DOM ઉમેર્યા વગર જૂથ બનાવે છે.
  • Smart (container) components data લાવે છે અને તર્ક સાચવે છે; dumb (presentational) components ફક્ત @Input દ્વારા બતાવે છે અને @Output દ્વારા મોકલે છે.
  • Dumb components ખૂબ ફરી વાપરી શકાય એવાં અને સહેલાઈથી ચકાસી શકાય એવાં હોય છે, કારણ કે એમને data ના સ્રોત વિશે કશી ખબર હોતી નથી.
  • દૂર દૂરનાં components વહેંચાયેલી service માં RxJS દ્વારા બદલાતી state વહેંચે છે.
  • યાદ રાખવાની કડી: લવચીકતા માટે content project કરો; smart components લાવે છે, dumb components બતાવે છે.

Study this properly

This page is the lesson to read. In Gri-Learn the same topic is a graded deck: the self-checks are scored and your weak topics are tracked. Free to start.

Start this topic

Already have an account? Sign in

More from Fundamentals of Angular (v17) for Single Page Applications

Gri-Learn · syllabus-mapped B.C.A. lessons in English, Hindi and Gujarati

Building Reusable UI Components & Design Patterns: reusable card, modal and alert components; component interaction with RxJS and Shared Services; ng-template, ng-container, ng-content; Smart vs Dumb Components · Fundamentals of Full Stack Web Development (Major-15-01) · Gri-Learn