برنامه نویسی

من به یک مدیر دولتی در انگولار نیاز ندارم یا فقط ورود او را به تاخیر می اندازم؟

هنگامی که یک Angular App می‌سازیم، ارتباط بین مؤلفه‌ها چیزی است که باید مراقب آن باشیم. می توانیم با رویدادهای ورودی و خروجی استفاده از والدین به فرزند را شروع کنیم. فقدان ارتباط ورودی و خروجی تنها ارتباط والدین به فرزند یا برعکس است، اما زمانی که برنامه با مسیریابی و بیشتر از اجزای والدین و فرزندان شروع به رشد می کند. از این رو، گام بعدی استفاده از خدمات Angular با است Rxjs.

سرویس‌های Rxjs در برنامه‌های کوچک با حالت کم به خوبی کار می‌کنند. تزریق یک سرویس با a BehaviorSubject برای همگام نگه داشتن آن، آن را مشترک کنید، اما اگر برنامه شما دارای نهادها، تنظیمات و پیکربندی‌های کاربر زیادی است و این تغییرات باید در چندین مؤلفه منعکس یا واکنش نشان دهند، فقط استفاده از سرویس‌ها کمی سخت می‌شود که نگهداری شود یا شاید نباشد.

ما باید از مسئولیت یک جزء یا زمان بازسازی آن آگاه باشیم. ایجاد یک مؤلفه جدید برای یک محدوده خاص و مراقبت از زمانی که یک مؤلفه دارای خدمات زیادی تزریق می شود یک پرچم قرمز است. بیایید یک مثال کوچک نشان دهیم.

سناریو

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

  • هر بخش باید اجازه ذخیره داده ها در حالت را بدهد.

  • خانه باید داده های هر بخش را ارائه دهد.

  • هر سفارش تخفیف از موجودی.

ما از Rxjs Behavior Subject برای حفظ حالت و برخی از عملگرهای rxjs برای ساده سازی و ترکیب برخی از عملگرها استفاده خواهیم کرد.

راه اندازی پروژه

ابتدا با استفاده از Angular CLI، پروژه را ایجاد کنید:

> ng new angular-and-states
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? CSS
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

پس از اتمام، از ترمینال به دایرکتوری جدید بروید و دو صفحه ایجاد کنید. home و settings با استفاده از Angular/CLI و اجرای دستور ng g c و نام جزء

PS C:\Users\dany.paredes\Desktop\angular-and-states> ng g c /pages/payments
CREATE src/app/pages/payments/payments.component.html (23 bytes)
CREATE src/app/pages/payments/payments.component.spec.ts (640 bytes)
CREATE src/app/pages/payments/payments.component.ts (283 bytes)
CREATE src/app/pages/payments/payments.component.css (0 bytes)
UPDATE src/app/app.module.ts (774 bytes)
PS C:\Users\dany.paredes\Desktop\angular-and-states> ng g c /pages/orders  
CREATE src/app/pages/orders/orders.component.html (21 bytes)
CREATE src/app/pages/orders/orders.component.spec.ts (626 bytes)
CREATE src/app/pages/orders/orders.component.ts (275 bytes)
CREATE src/app/pages/orders/orders.component.css (0 bytes)
UPDATE src/app/app.module.ts (862 bytes)
PS C:\Users\dany.paredes\Desktop\angular-and-states> ng g c /pages/profile
CREATE src/app/pages/profile/profile.component.html (22 bytes)
CREATE src/app/pages/profile/profile.component.spec.ts (633 bytes)
CREATE src/app/pages/profile/profile.component.ts (279 bytes)
CREATE src/app/pages/profile/profile.component.css (0 bytes)
UPDATE src/app/app.module.ts (954 bytes)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برای پیمایش، ناوبری جزء را با استفاده از همان دستور اما در مسیر ایجاد کنید components:

ng g c /components/navigation
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نشانه گذاری navigation.component.html را با استفاده از دستورالعمل ها برای پیمایش به روز کنید:

<a [routerLink]="['']">Home</a>
<a [routerLink]="['payments']">Payments</a>
<a [routerLink]="['orders']">Orders</a>
<a [routerLink]="['profile']">Profile</a>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس علامت گذاری پیش فرض را در قسمت حذف کنید app.component.html و علامت گذاری زیر را با اضافه کنید <router-outlet></router-outlet>

<h1>App</h1>
<app-navigation></app-navigation>
<router-outlet></router-outlet>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اضافه کردن مسیرها در app-routing.module.ts

const routes: Routes = [
  {
    component: HomeComponent,
    path: ''
  },
  {
    component: OrdersComponent,
    path: 'orders'
  },

  {
    component: PaymentsComponent,
    path: 'payments'
  },
  {
    component: ProfileComponent,
    path: 'profile'
  }
];
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

دستور را ذخیره و اجرا کنید ng s -o، و برنامه باید مؤلفه خانه را با پیمایش ارائه دهد.

5c232c25 cd43 46a0 902e 1cb759f9148d

افزودن ایالت با خدمات

ما باید وضعیت را برای هر بخش ذخیره کنیم، و برای هر یک از “پروفایل”، “سفارش ها” و “پرداخت ها” یک سرویس ایجاد کنیم.

با استفاده از angular/cli اجرا کن ng g s /services/profile برای به اشتراک گذاری داده های مربوط به نمایه بین مؤلفه ها با استفاده از BehaviorSubject.

درباره BehaviorSubject بیشتر بخوانید

دو ویژگی ایجاد کنید: –nameSubject$ ss یک نمونه از BehaviorSubject، و با مقدار null مقداردهی اولیه می شود.

  • این name$ اموال عمومی که فاش می کند nameSubject به عنوان یک قابل مشاهده
@Injectable({
  providedIn: 'root'
})
export class ProfileService {

  private nameSubject = new BehaviorSubject<string | null>(null);
  public name$ = this.nameSubject.asObservable()

  public saveName(name: string) {
    const message = `Hi ${name} `
    this.nameSubject.next(message);
  }

}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

فرآیند را برای PaymentService، که موجودی حساب را نگه می دارد.

ng g s /services/payments
CREATE src/app/services/payments.service.spec.ts (367 bytes)
CREATE src/app/services/payments.service.ts (137 bytes)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ایجاد دو ویژگی، paymentSubject$ شروع با تعادل در 0 و paymentBalance$و دو روش اضافه کنید:

import {Injectable} from '@angular/core';
import {BehaviorSubject} from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class PaymentsService {

  private paymentSubject$ = new BehaviorSubject<number | null>(null);
  public paymentBalance$ = this.paymentSubject.asObservable()

  public updateBalance(balance: number) {
    const currentBalance = this.paymentSubject.getValue();
    if (currentBalance) {
      const totalBalance = currentBalance - balance;
      this.paymentSubject$.next(totalBalance);
    }
  }

  public addBalance(balance: number) {
    this.paymentSubject$.next(balance);
  }

}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در نهایت، ایجاد کنید OrdersServices برای انجام کلیه سفارشات

ng g s /services/orders  
CREATE src/app/services/orders.service.spec.ts (357 bytes)
CREATE src/app/services/orders.service.ts (135 bytes)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این سرویس حاوی آرایه ای از orderIds است.

import {Injectable} from '@angular/core';
import {BehaviorSubject} from 'rxjs/internal/BehaviorSubject';

@Injectable({
  providedIn: 'root'
})
export class OrdersService {

  private orderSubject = new BehaviorSubject<number[]>([]);
  public orders$ = this.orderSubject.asObservable()

  public addOrder(orderId: number) {
    const orders = [...this.orderSubject.value, orderId]
    this.orderSubject.next(orders);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

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

استفاده از وضعیت خدمات در کامپوننت ها

ما خدماتی برای ذخیره داده ها داریم. قدم بعدی ما استفاده از آن در هر صفحه است. فرآیند تزریق سرویس به کامپوننت و استفاده از روش و موضوع برای دریافت ارزش از سرویس است.

این ProfileComponent، امکان ذخیره نام او، ذخیره آن در قابل مشاهده و ارائه آن را فراهم می کند saveName روش از سرویس

ابتدا سرویس را تزریق کنید ProfileService، و یک متغیر جدید اضافه کنید name$ برای پیوند با قابل مشاهده name$ از سرویس

بعد، یک روش جدید اضافه کنید، save، با نام پارامتر، در بدنه متد، برای استفاده از saveName از سرویس

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

import { ProfileService } from './../../services/profile.service';
import { Component, inject, OnInit } from '@angular/core';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css'],
})
export class ProfileComponent {
  name$ = this.profileService.name$;

  constructor(private profileService: ProfileService) {}

  save(name: string) {
    this.profileService.saveName(name);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در نشانه گذاری HTML مؤلفه، یک ورودی جدید با متغیر الگو #name اضافه کنید تا به مقدار ورودی دسترسی پیدا کنید، و یک دکمه برای فراخوانی اضافه کنید. save روش، عبور از متغیر name.value به روش اشاره دارد.

برای ارائه نام، از لوله استفاده کنید async اشتراک در name$ قابل مشاهده برای نشان دادن nameSaved در خدمت

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

<h3>Please type your Name:</h3>
<input #name type="text">
<button (click)="save(name.value)">Save</button>
<span *ngIf="(name$ | async ) as nameSaved">{{nameSaved}}</span>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما قبلاً وضعیت را برای بخش نمایه تنظیم کردیم، تغییرات را ذخیره کردیم و برنامه را با آن اجرا کردیم ng s -o. برنامه را به بخش نمایه باز می کند، نام شما را اضافه می کند و بین بخش های دیگر حرکت می کند و نام را ذخیره می کند.

021c6389 6c31 464b 834d 8fe3c0206e33

برای پرداخت همین مراحل را تکرار کنید.

جزء پرداخت

import {PaymentsService} from './../../services/payments.service';
import {Component} from '@angular/core';

@Component({
  selector: 'app-payments',
  templateUrl: './payments.component.html',
  styleUrls: ['./payments.component.css']
})
export class PaymentsComponent {

  balance$ = this.paymentService.paymentBalance$;

  constructor(private paymentService: PaymentsService) {

  }

  updateBalance(balance: HTMLInputElement) {
    this.paymentService.addBalance(balance.valueAsNumber);
  }

}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نشانه گذاری HTML را با ورودی و دکمه به روز کنید و در تعادل$ قابل مشاهده مشترک شوید.

<h2>Add balance:</h2>
<input #payment type="number">
<button (click)="updateBalance(payment)">Update</button>
<span *ngIf="(balance$ | async ) as balance">You current Balance is: {{balance$ | currency}}</span>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

جزء سفارشات

فرآیند را با دستورات تکرار کنید اما با تغییرات جزئی، تنها تفاوت این است که سفارشات یک آرایه هستند و ما از ngFor برای ارائه تمام بخش ها

import { Component, OnInit } from '@angular/core';
import { OrdersService } from 'src/app/services/orders.service';

@Component({
  selector: 'app-orders',
  templateUrl: './orders.component.html',
  styleUrls: ['./orders.component.css'],
})
export class OrdersComponent {
  orders$ = this.ordersService.orders$;

  constructor(private ordersService: OrdersService) {}

  addOrder(order: HTMLInputElement) {
    if (order.value) {
      this.ordersService.addOrder(order.valueAsNumber);
      order.value = '';
    }
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

<h2>Add your order</h2>
<input #order type="number">
<button (click)="addOrder(order)">add order</button>
<div *ngIf="(orders$ | async ) as orders">
  Your current active orders are:
  <div *ngFor="let order of orders">
    {{order}}
  </div>
</div>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در نهایت، ما یک حالت در موجودیت‌های خود داریم و چالش بعدی خواندن مقدار هر سرویس برای نمایش داده‌ها در مؤلفه خانه است.

7b30ec74 51b9 49e1 bd9a 2342e878ea7d

ایالات را ترکیب کنید و همگام سازی کنید

ما در برنامه خود سه مقدار داریم:

  • مانده پرداخت

  • اطلاعات پروفایل

  • سفارشات

اولین چالش ما هنگام اضافه کردن یک سفارش جدید در OrderComponent برای تخفیف موجودی در paymentService.

در orders.component، باید به نکات زیر اشاره کنیم:

  • اضافه کردن paymentService و ordersService در سازنده

  • یک متغیر جدید برای ذخیره سازی اعلام کنید currentBalance.

  • را ویرایش کنید addOrder برای به روز رسانی موجودی با 2 هنگام ارسال سفارش

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

import {PaymentsService} from '../../services/payments.service';
import {Component} from '@angular/core';
import {OrdersService} from 'src/app/services/orders.service';
import {startWith} from 'rxjs/operators';

@Component({
  selector: 'app-orders',
  templateUrl: './orders.component.html',
  styleUrls: ['./orders.component.css'],
})
export class OrdersComponent {
  orders$ = this.ordersService.orders$;
  currentBalance$ = this.paymentService.paymentBalance$

  constructor(
    private ordersService: OrdersService,
    private paymentService: PaymentsService
  ) {

  }

  addOrder(order: HTMLInputElement) {
    this.ordersService.addOrder(order.valueAsNumber);
    this.paymentService.updateBalance(2);
    order.value = '';
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در نشانه گذاری HTML، اشتراک را اضافه کنید currentBalance$. اگر نه، الگو را نشان دهید noBalance و دکمه را غیرفعال کنید اگر balance= 0 باشد، کد نهایی به شکل زیر است:

<div *ngIf="currentBalance$ | async as balance; else noBalance">
  <h2>You have {{balance | currency }} as balance, add your orders</h2>
  <input #order type="number">
  <button (click)="addOrder(order)" [disabled]="balance <= 0">add order</button>
</div>
<ng-template #noBalance>
  <h2> Insuficient Balance, please add.</h2>
</ng-template>
<div *ngIf="orders$ | async  as orders">
  You have ({{orders.length}}) orders.
  <div *ngFor="let order of orders">
    {{order}}
  </div>
</div>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تغییرات را ذخیره کنید و برنامه دوباره بارگیری شود. یک موجودی اولیه اضافه کنید، و وقتی سفارش را اضافه می کنید، موجودی برای هر سفارش.

93411e35 16cf 43bd bdb5 3a3a932c8524

همه ایالات را ترکیب کنید

چالش با Orders ساده بود، ما یک سرویس واحد اضافه کردیم، اما چه چیزی می خواهیم از همه سرویس ها داده دریافت کنیم؟

Rxj ها چند عملگر را برای ترکیب Observables ارائه می دهند merge و concat، اما در سناریوی ما از آن استفاده می کنیم combineLatest.

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

  • تزریق کنید ProfileService، OrdersService، و PaymentsService

  • استفاده کنید combineLatest اپراتور برای ترکیب هر داده خدمات در یک شی واحد و مشترک شدن در قالب

import { Component } from '@angular/core';
import { combineLatest } from 'rxjs';
import { OrdersService } from 'src/app/services/orders.service';
import { PaymentsService } from 'src/app/services/payments.service';
import { ProfileService } from 'src/app/services/profile.service';
import { map } from 'rxjs/operators';
@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css'],
})
export class HomeComponent {
  customerStatus$ = combineLatest([
    this.paymentService.paymentBalance$,
    this.orderService.orders$,
    this.profileService.name$,
  ]).pipe(
    map(([balance, orders, profileName]) => ({ balance, orders, profileName }))
  );

  constructor(
    private profileService: ProfileService,
    private orderService: OrdersService,
    private paymentService: PaymentsService
  ) { }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نشانه گذاری HTML subscribe به قابل مشاهده با استفاده از pipe async نام، تعادل و دستورات را ارائه می دهد.

<div *ngIf="customerStatus$ | async as customerStatus">
  <p>Hey! {{customerStatus.profileName}}, your balance is {{ customerStatus.balance | currency }}
    in {{customerStatus.orders.length}}</p>

  <div *ngFor="let order of customerStatus.orders">
    {{ order }}
  </div>

</div>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تغییرات را ذخیره کنید و زمانی که هر یک از قابل مشاهده‌ها مؤلفه اصلی را منتشر می‌کند، مرورگر دوباره بارگیری می‌شود تا داده‌های هر یک را دریافت کند.

8474e31e c550 462d 814c 21bdcb3b818e

ما سه تزریق در home.component.ts برای ارائه اطلاعات جزء این کار می کند اما سر و صدای بیش از حد در home.component.ts; شاید بتوانیم آن را ساده کنیم.

موضوع رفتار را متمرکز کنید

یکی از راه حل ها ایجاد است appService; تمام وضعیت مورد نیاز برنامه ما را ارائه می دهد. به جای تزریق همه خدمات به هر صفحه، ما یک نقطه ورود داریم. شروع کنیم:

  • یک سرویس جدید ایجاد کنید AppService

  • تزریق کنید ProfileService، OrdersService، و PaymentsService

  • استفاده کنید combineLatest اپراتور برای ترکیب هر داده سرویس در یک شی واحد و نمایش آن در ویژگی customerInfo$

  • دو خاصیت اضافه کنید orders$ و balance$.

  • روش را اضافه کنید addOrder برای به روز رسانی موجودی و سفارشات.

import {Injectable} from '@angular/core';

import {ProfileService} from "./profile.service";
import {OrdersService} from "./orders.service";
import {PaymentsService} from "./payments.service";
import {map} from 'rxjs/internal/operators/map';
import {combineLatest} from 'rxjs';


@Injectable({
  providedIn: 'root'
})
export class AppService {
  public customerAndBalance$ = combineLatest([
    this.paymentService.paymentBalance$,
    this.profileService.name$,
  ]).pipe(
    map(([balance, name]) => ({balance, name}))
  );

  customer$ = this.profileService.name$;
  orders$ = this.orderService.orders$;
  balance$ = this.paymentService.paymentBalance$;

  constructor(
    private profileService: ProfileService,
    private orderService: OrdersService,
    private paymentService: PaymentsService
  ) {
  }

    //comment with ngJörger 
  addOrder(order: number) {
    this.orderService.addOrder(order);
    this.paymentService.updateBalance(1);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در home.component.html خدمات را حذف کرده و اضافه کنید appService در سازنده، و به روز رسانی مرجع customerStatus برای اشاره به customerInfo$ روش از appService.

ذخیره کنید، و همه چیز همانطور که انتظار می رود به کار خود ادامه می دهد.

import {Component} from '@angular/core';
import {HomeService} from "./home.service";

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css'],
})
export class HomeComponent {
  customerStatus$ = this.appService.customerInfo$;

  constructor(private appService: AppService) {
  }

}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سرویس خانه وابستگی های کمتری دارد، بنابراین کد ما تمیز به نظر می رسد. ما می توانیم راه حل خود را ساده کرده و مسئولیتی را به یک جزء خاص واگذار کنیم.

مسئولیت جزء

صفحه اصلی دارای دو بخش است که در صفحات تکرار می شود، نام کاربری با موجودی و لیست سفارشات.

بیایید با شروع کنیم OrderListComponent، با استفاده از Angular/CLI برای تولید کامپوننت جدید ng g c /components/orderlist:

  • تزریق کنید AppService در سازنده

  • یک را اعلام کنید orders$ قابل مشاهده برای خواندن تمام سفارشات در خدمات.

  • نشانه گذاری HTML را باز کنید و در آن مشترک شوید orders$ با استفاده از لوله قابل مشاهده است async و با آن تکرار کنید ngFor.

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

import {Component} from '@angular/core';
import {AppService} from "../../services/app.service";

@Component({
  selector: 'app-order-list',
  templateUrl: './order-list.component.html',
  styleUrls: ['./order-list.component.css']
})
export class OrderListComponent {

  orders$ = this.appService.orders$;

  constructor(private appService: AppService) {
  }

}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

<div *ngIf="orders$ | async  as orders">
  You have ({{orders.length}}) orders.
  <div *ngFor="let order of orders">
    {{order}}
  </div>
</div>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

فرآیند دقیق با پیام مشتری یک مؤلفه را ایجاد می کند Angular/CLI.

  • دستور را اجرا کنید ng g c /components/customer-message

  • تزریق کنید AppService در سازنده

  • الف را اعلام کنید customerInfo$ قابل مشاهده برای خواندن customerAndBalance$ ارزش.

  • نشانه گذاری HTML را باز کنید و در آن مشترک شوید customerInfo$ با استفاده از لوله قابل مشاهده است async.

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

import {Component} from '@angular/core';
import {AppService} from "../../services/app.service";


@Component({
  selector: 'app-customer-message',
  templateUrl: './customer-message.component.html',
  styleUrls: ['./customer-message.component.css']
})
export class CustomerMessageComponent {

  public customerInfo$ = this.appService.customerAndBalance$;

  constructor(private appService: AppService) {
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

<div *ngIf="customerInfo$ | async as customer">
  <div *ngIf="customer.name && customer.balance; else updateInfo">
    <p>Hey! {{customer.name}}, your balance is {{ customer.balance | currency }}</p>
  </div>
</div>
<ng-template #updateInfo>
  Please add your name and balance
</ng-template>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما قبلا AppService را تزریق کرده ایم orderList و customerMessage، که به ساده سازی برنامه و بازسازی سایر مؤلفه ها کمک می کند.

اجزای Refactor

ما دو جزء برای ساده کردن خانه و سفارشات داریم.

کامپوننت Home مانند یک ظرف برای customerMessage و orderList اجزاء، بنابراین اجازه می دهد تا تمیز کنیم:

  • تزریق appService را از سازنده حذف کنید.

  • در قالب، از مولفه های customer-message و listOrder استفاده کنید.

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

import {Component} from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css'],
})
export class HomeComponent {

}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

<app-customer-message></app-customer-message>
<app-order-list></app-order-list>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مولفه Orders با استفاده از AppService و جزء orderlist ساده می شود.

  • تزریق کنید AppService در سازنده

  • الف را اعلام کنید balance$ قابل مشاهده برای خواندن مقدار تعادل از AppService.

  • را به روز کنید addOrder روش برای فراخوانی همان از appService.

  • نشانه گذاری HTML را باز کنید و در آن مشترک شوید balance$ با استفاده از لوله قابل مشاهده است async.

  • اضافه کردن customer و orderlist جزء برای نمایش داده های کاربر و لیست سفارشات.

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

import {Component} from '@angular/core';
import {AppService} from "../../services/app.service";

@Component({
  selector: 'app-orders',
  templateUrl: './orders.component.html',
  styleUrls: ['./orders.component.css'],
})
export class OrdersComponent {


  balance$ = this.appService.balance$

  constructor(
    private appService: AppService
  ) {

  }

  addOrder(order: HTMLInputElement) {
    this.appService.addOrder(order.valueAsNumber)
    order.value = '';
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

<div *ngIf="balance$ | async as balance; else noBalance">
  <app-customer-message></app-customer-message>
  <input #order type="number">
  <button (click)="addOrder(order)" [disabled]="balance <= 0">add order</button>
</div>
<ng-template #noBalance>
  <h2> Insufficient Balance, please add.</h2>
</ng-template>

<app-order-list></app-order-list>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

آنچه می آموزم

مثال کوچکی بود. ما وقت داشتیم که بدون زمان، بازار، سرعت تیم و فشار شرکت، مرور کنیم و وقت بگذاریم.

  • از Rxjs Observable استفاده کنید، که به ما اجازه می دهد تا یک برنامه واکنشی را سریع و بدون پیچیدگی زیاد بسازیم.

  • وقتی هر موجودیتی خدمات خود را برای حفظ وضعیت دارد، اگر یک جزء به همه اطلاعات نیاز داشته باشد، نیاز به تزریق همه آنها دارد.

  • برای کاهش مقدار تزریق، ما همه خدمات “پل” را برای ارتباط با موضوعات رفتاری متعددی مانند AppService

  • ما باید تشخیص دهیم که کدام مؤلفه ها می توانند به صورت ایزوله کار کنند، عملکردی را بدون وابستگی های زیاد ارائه دهیم و مؤلفه های خود را ساده کنیم.

  • استفاده از الگوی هوشمند و اجزای dump به ساده سازی ترکیب اجزا کمک می کند.

آیا به مدیر دولتی نیاز دارم؟

اگر برنامه شما یک MVP یا کوچک مانند این است، BehaviorSubject مشکلی ندارد. من می‌خواهم کمی وقت بگذارم تا دوباره همان برنامه را با استفاده از یک مدیر ایالتی بسازم NgRx یا NGXS.

به زودی میبینمت!

عکس از Agê Barros در Unsplash

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا