تقویت رابط کاربری و پایگاه داده در اپلیکیشن انگولار

27 اسفند 1398

سلام دوستان. با آخرین قسمت از سری آموزش مقدماتی انگولار در خدمت شما هستیم. این جلسه به تقویت رابط کاربری در انگولار و پایگاه داده اپلیکیشن انگولاری می پردازیم.

کامپوننت های متریال دیزاین انگولار، برای تقویت UI/UX

تعدادی کتابخانه حاوی کامپوننت های بسیار قدرتمند وجود دارد که امکان ساخت یک رابط کاربری در انگولار را در کوتاه ترین زمان ممکن می سازد. این کتابخانه ها دارای مودال ها، پاپ آپ ها، کاردها، میست ها، منوها و بسیار چیزهای دیگر هستند. به کمک این UI ها می توانید بلوک های مختلفی برای اپلیکیشن خود بسازید که غالبا با html ،css و javascript ساخته شده اند.

از پرکاربردترین کتابخانه ها می توان به دو کتابخانه ی Angular Material و ngx-bootstrap اشاده کرد. کتابخانه ی Angular Material، کتابخانه ی رسمی خود فریم ورک انگولار است و دارای کامپوننت های زیادی می باشد.

از طرفی دیگر، کتابخانه ی ngx-bootstrap دارای یک سری کامپوننت هاست که بر پایه ی فریم ورک بوت استرپ ساخته شده اند.

ما در اپلیکیشن نمونه ی خود، از طرح بندی ها یا layout های مختلفی استفاده خواهیم کرد. در زیر به برخی از مهم ترین کامپوننت های سازنده ی نماهای مختلف اپلیکیشن اشاره می کنیم.

نمای مربوط به دسته بندی های کلی (Categories view)

  • یک لیست که مفاهیم مختلفی را در انگولار به نمایش می گذارد.
  • Material Components: کامپوننت لیست شکلی (List component) که دسته بندی ها را نمایش می دهد - و کامپوننت دیگری که تگ های هر دسته بندی را نمایش می دهد.

نمای مربوط به دسته بندی سوالات (Category Questions view)

  • یک نما (view) که همه ی سوالات مربوط به به یک دسته بندی را نمایش می دهد.
  • Material Components: کامپوننت لیست شکلی که سوالات را نمایش می دهد - کامپوننت دکمه (Button component) - کامپوننت پیغام برای مودال (Dialog component).

نمای مربوط به جواب یک سوال (Question Answers view)

  • یک نما برای نمایش همه ی جواب های مربوط به یک سوال خاص
  • Material Components: کامپوننت لیست شکلی که جواب ها را نمایش می دهد - کامپوننت دکمه (Button component) - کامپوننت پیغام برای مودال (Dialog component).

نمای مربوط به مودال سوال و پاسخ جدید (New Question and New Answer modals)

  • مودالی برای ایجاد و ویرایش سوالات و پاسخ ها
  • Material Components: کامپوننت پیغام برای مدیریت و کنترل مودال

همچنین از متریالی کامپوننتی به نام Toolbar برای نمایش مسیر در بالای صفحه استفاده خواهیم کرد.

مسیر دهی دقیق

افزودن بک اند به پروژه ی انگولاری

یک موضوع مهم برای ایجاد یک اپلیکیشن این است که آن را برای تغییر و تحول، با استفاده از سرویس ها و دریافت و قرار دادن داده ها از بک اند آماده کنیم.

همانطور که می دانید، روش های مختلفی برای قرار دادن داده در اپلیکیشن و پیاده سازی بک اند وجود دارد. در این آموزش، ما نحوه ی صرف داده ها را با استفاده از یک فایل json حاوی داده های ساختگی، شرح خواهیم داد. در روش هایی دیگر، ممکن است از REST API ها و دیتابیس مونگو نیز، برای بک اند اپلیکیشن، استفاده شود.

هر دو روش ذکر شده در بالا برای بک اند، باید به فکر مشکلات سمت اپلیکیشن نیز باشید. مشکلاتی مثل چگونگی نحوه ی انجام تماس با داده (data calls). این کار کاملا مستقل از پیاده سازی بک اند انجام می شود. ما در ادامه، در رابطه با مدل ها، سرویس ها (models) و سرویس ها (services) و چگونگی کنار هم قرار دادن این موارد صحبت خواهیم کرد.

مدل های دامنه (Domain Models)

مدل دامنه برای تعریف و اجرا کردن منطق های تجاری (business logic) در اپلیکیشن مهم هستند. مخصوصا در رابطه با زمانی که اپلیکیشن بزرگتر شده و کاربران بیشتری از آن استفاده کنند. در این حال، بسیار مهم است که اپلیکیشن خود را به گونه ای طراحی کنیم که منطق ها را از کامپوننت ها، به کلاس های مجزا (یا مدل ها)، انتقال دهد. کلاس ها یا مدل هایی که بلافاصله قابل فراخوانی یا تماس باشند.

سرویس های داده (Data Services)

فریم ورک انگولار ما را قادر می سازد تا «سرویس های داده ای زیربرنامه ای چند گانه» ایجاد کنیم (multiple reusable data services) و آن ها را به کامپوننت های مورد نظر تزریق یا اعمال کنیم. با اختصاص وظیفه ی دسترسی داده ها به سرویس های جداگانه، حجم کامپوننت ها کم شده و تمرکز بر روی نمای آن ها گذاشته خواهد شد. این کار (اختصاص وظیفه ی دسترسی داده ها به سرویس های جداگانه) باعث می شود که تست کردن کامپوننت ها هم راحت تر شود.

ما در اپلیکیشن خود، یک مدل را برای دسته بندی های سوالات مشخص کردیم و آن را از فایل json بیرون خواهیم کشید. این مدل توسط categories.service.ts مورد استفاده قرار خواهد گرفت.

//in category.model.ts
export class CategoryModel {
  slug: string;
  title: string;
  image: string;
  description: string;
  tags: Array<Object>;
}

//in categories.service.ts
getCategories(): Promise<CategoryModel[]> {
  return this.http.get("./assets/categories.json")
  .toPromise()
  .then(res => res.json() as CategoryModel[])
}

همچنین از سرویس زیر (کدهایی که در زیر نوشته شده) در فایل categories.resolver.ts استفاده می کنیم.

//in categories.resolver.ts
import { Injectable } from '@angular/core';
import { Resolve } from "@angular/router";
import { CategoriesService } from "../services/categories.service";

@Injectable()
export class CategoriesResolver implements Resolve<any> {

  constructor(private categoriesService: CategoriesService) { }

  resolve() {
    return new Promise((resolve, reject) => {

      let breadcrumbs = [
        { url: '/', label: 'Categories' }
      ];

      //get categories from local json file
      this.categoriesService.getCategories()
      .then(
        categories => {
          return resolve({
            categories: categories,
            breadcrumbs: breadcrumbs
          });
        },
        err => {
          return resolve(null);
        }
      )
    });
  }
}

هر زمان که ما یک سرویس جدید را اضافه می کنیم، بخاطر داشته باشید که خود انگولار به صورت پیشفرض نمی داند که چگونه باید این سرویس را بسازد. اگر همین الان کد بالا را اجرا کنیم، با اروری از طرف انگولار مواجه خواهیم شد. بعد از ایجاد سرویس،  باید این سرویس را به انگولار معرفی کنیم و به انگولار نحوه ی ساخت آن را بیاموزیم!

دو راه برای این کار وجود دارد:

  • در خود کامپوننت
  • درون مدل (NgModule)

ما از روش دوم استفاده می کنیم. یعنی سرویس را در فایل app.module.ts معرفی می کنیم. (کد زیر را در فایل app.module.ts اضافه می کنیم)

//in app.module.ts
@NgModule({
  declarations: [
    AppComponent,
    CategoriesComponent,
    CategoryQuestionsComponent,
    NewQuestionModalComponent,
    NewAnswerModalComponent,
    UpdateAnswerModalComponent,
    QuestionAnswersComponent,
    DeleteQuestionModalComponent,
    DeleteAnswerModalComponent
  ],
  imports: [
    RouterModule.forRoot(routes,
      { useHash: false }
    ),
    SharedModule
  ],
  entryComponents: [

  ],
  providers: [
    CategoriesService,
    QuestionsService,
    AnswersService,
    CategoryQuestionsResolver,
    CategoriesResolver,
    QuestionAnswersResolver
  ],
  bootstrap: [AppComponent]
})

export class AppModule { }

در جایی قبلا خواندم که در رابطه با Dependency Injection در انگولار نوشته بود:

به خاطر داشته باشید که ما سرویس های داده (data services) را فقط به کامپوننت هایی که به آن ها نیاز دارند «تزریق یا inject» می کنیم.

این گفته به دلایل زیر اشتباه است:

  • کامپوننت ما باید نحوه ی ایجاد سرویس را بداند. هر زمانی که ما سازنده ی سرویس را عوض کردیم، باید تمام مکان هایی که در آن ها سرویس را ساخته ایم، پیدا کرده و درستشان کنیم. گفته ی بالا احتمال ارور و ریسک را در تست کردن اپلیکیشن، افزایش می دهد.
  • در این حالت هر بار که از سرویسی استفاده کنیم، باید آن سرویس را مجددا ایجاد کنیم. خب! اگر سرویس ما نیاز به دریافت داده های کش (cache یا حافظه ی پنهان) داشت و باید داده های کش را گرفته و نمایش می داد، آنوقت چه می شد؟ بله! در این حالت این کار امکان پذیر نخواهد بود.

اجتناب از چنین اشتباهاتی بسیار مهم است و دلیلی هم برای انجام چنین اشتباهاتی وجود ندارد.

به پایان قسمت هفتم رسیدیم. این جلسه راجع به تقویت رابط کاربری در انگولار و پایگاه داده ی اپلیکیشن صحبت کردیم. در قسمت بعدی، درباره ی نسخه های جدیدتر انگولار یعنی ورژن های 8 و 9 انگولار (Angular 8 و Angular 9) صحبت می کنیم و راجع به قدم بعدی در مسیر آموزش آنگولار بحث خواهیم کرد.


منبع: سایت Angular Templates

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش مقدماتی انگولار توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.