کتابخانهی RxJS، جزو پایهای کار با برنامههای Angular است و سادهترین روش کار با آن، تعریف یک سطر ذیل است:
به این ترتیب تمام عملگرهای RxJS مانند map ،do ،catch و غیره نیز import خواهند شد. اما این سادگی ... به قیمت افزوده شدن یک بستهی 586 KB (غیرفشرده) به فایلهای نهایی، تمام خواهد شد.
روشهای مختلف import ویژگیهای کتابخانهی RxJS
الف) import همه چیز به صورت یکجا
یک مثال
این روش بسیار سادهاست. اما سبب import کامل یک کتابخانهی 586 KB نیز میشود.
ب) تنها import ویژگیهای مورد نیاز
به این روش «patching the Observable prototype» نیز گفته میشود.
یک مثال
مزیت این روش، کاهش قابل ملاحظهی حجم نهایی برنامه است. فقط باید دقت داشت که متدهای مورد نیاز، حتما import شده باشند.
ج) فراخوانی مستقیم متدهای RxJS نه از طریق Observable
یک مثال
در این حالت کد بیشتری باید نوشته شود و مزیت اطلاعات نوع متد را نیز از دست میدهیم. از این جهت که این متدها زمانیکه با این روش import میشوند، any را بازگشت میدهند (Function.prototype.call خروجی از نوع any دارد).
مقید کردن برنامه به عدم استفاده از حالت «الف» و اجبار به استفاده از حالت «ب»
اگر به ریشهی پوشهی پروژههای مبتنی بر Angular CLI دقت کنید، فایل tslint.json نیز در آنها قابل مشاهده است و اگر افزونهی VSCode آنرا نیز نصب کرده باشید، در حین کار با VSCode، خطاهای مرتبط را درون ادیتور مشاهده خواهید کرد. TSLint، قابلیت توسعه داشته و یک نمونهی از اینها، بستهی TSLint rules for RxJS است. برای نصب آن ابتدا دستور ذیل را صادر کنید:
سپس فایل tslint.json را گشوده و تغییرات ذیل را به آن اعمال نمائید:
rxjs-no-wholesale آن سبب منع درج حالت «الف» میشود و سایر حالات روش «ب» را تشویق میکنند.
مدیریت بهتر حالت «ب» یا «تنها import ویژگیهای مورد نیاز»
زمانیکه از روش «ب» استفاده میکنیم، کلاسهای سرویس برنامه پر خواهند شد از کدهای تکراری ذیل:
در اینجا هر متدی را که نیاز است باید یکبار import کرد و اینکار را باید به ازای تکتک سرویسهای برنامه نیز تکرار نمود.
برای مدیریت بهتر اینکار، فایل جدیدی را به نام src\app\shared\rxjs-operators.ts ایجاد میکنیم؛ با محتوای ذیل:
در اینجا تمام importهای مورد نیاز برنامه به صورت یکجا درج میشوند.
سپس کافی است به فایل src\app\app.module.ts مراجعه کرده و این فایل را import کنیم:
با اینکار سبب خواهیم شد تا دیگر در سرویسهای برنامه (و تمام قسمتهای آن) نیازی به تعریفهای تکراری RxJS وجود نداشته باشد و تنها تعریفی که در آنجا نیاز است، یک مورد ذیل است:
علت اینجا است، همانطور که عنوان شد، به این روش «patching the Observable prototype» نیز گفته میشود. به این معنا که این عملگرها و یا افزونهها، جزئی از کلاس Observable میشوند و در تمام قسمتهای برنامه، پس از import آنها قابل دسترسی خواهند بود. بنابراین با یکبار import فایل rxjs-operators.ts، دیگر نیازی به تعریف مجدد آن نخواهد بود.
import {Observable} from 'rxjs';
روشهای مختلف import ویژگیهای کتابخانهی RxJS
الف) import همه چیز به صورت یکجا
import Rx from "rxjs/Rx";
Rx.Observable.of(1, 2, 3).map(i => i.toString());
ب) تنها import ویژگیهای مورد نیاز
import { Observable } from "rxjs/Observable"; import "rxjs/add/observable/of"; import "rxjs/add/operator/map";
یک مثال
Observable.of(1, 2, 3).map(i => i.toString());
ج) فراخوانی مستقیم متدهای RxJS نه از طریق Observable
import { Observable } from "rxjs/Observable"; import { of } from "rxjs/observable/of"; import { map } from "rxjs/operator/map";
const source = of(1, 2, 3); const mapped = map.call(source, i => i.toString());
مقید کردن برنامه به عدم استفاده از حالت «الف» و اجبار به استفاده از حالت «ب»
اگر به ریشهی پوشهی پروژههای مبتنی بر Angular CLI دقت کنید، فایل tslint.json نیز در آنها قابل مشاهده است و اگر افزونهی VSCode آنرا نیز نصب کرده باشید، در حین کار با VSCode، خطاهای مرتبط را درون ادیتور مشاهده خواهید کرد. TSLint، قابلیت توسعه داشته و یک نمونهی از اینها، بستهی TSLint rules for RxJS است. برای نصب آن ابتدا دستور ذیل را صادر کنید:
npm install rxjs-tslint-rules --save-dev
{ "rulesDirectory": [ "node_modules/codelyzer" ], "extends": [ "rxjs-tslint-rules" ], "rules": { "rxjs-add": { "severity": "error" }, "rxjs-no-patched": { "severity": "error" }, "rxjs-no-unused-add": { "severity": "error" }, "rxjs-no-wholesale": { "severity": "error" }, "rxjs-no-subject-unsubscribe": { "severity": "error" },
مدیریت بهتر حالت «ب» یا «تنها import ویژگیهای مورد نیاز»
زمانیکه از روش «ب» استفاده میکنیم، کلاسهای سرویس برنامه پر خواهند شد از کدهای تکراری ذیل:
import 'rxjs/add/operator/map'; import 'rxjs/add/operator/do'; import 'rxjs/add/operator/catch';
برای مدیریت بهتر اینکار، فایل جدیدی را به نام src\app\shared\rxjs-operators.ts ایجاد میکنیم؛ با محتوای ذیل:
// define the rxjs operators needed by your app // see node_module/rxjs/Rx.js for more // statics import "rxjs/add/observable/from"; import "rxjs/add/observable/throw"; // operators import "rxjs/add/operator/catch"; import "rxjs/add/operator/combineLatest"; import "rxjs/add/operator/debounceTime"; import "rxjs/add/operator/delay"; import "rxjs/add/operator/distinctUntilChanged"; import "rxjs/add/operator/do"; import "rxjs/add/operator/filter"; import "rxjs/add/operator/finally"; import "rxjs/add/operator/first"; import "rxjs/add/operator/ignoreElements"; import "rxjs/add/operator/let"; import "rxjs/add/operator/map"; import "rxjs/add/operator/mapTo"; import "rxjs/add/operator/mergeMap"; import "rxjs/add/operator/startWith"; import "rxjs/add/operator/switchMap"; import "rxjs/add/operator/takeUntil"; import "rxjs/add/operator/withLatestFrom"; import "rxjs/add/operator/takeUntil"; import "rxjs/add/operator/take";
سپس کافی است به فایل src\app\app.module.ts مراجعه کرده و این فایل را import کنیم:
// import RxJs needed operators only once import "./shared/rxjs-operators"; //... @NgModule({ //...
import { Observable } from "rxjs/Observable";