قرار بود با استفاده از redis cache کار سبد خرید رو پیاده سازی کنم. همه چیز از catalog-detail component شروع میشه که افزودن به سبد خرید رو می زنیم. ریدایرکت میشیم به basket-list component و لیست خرید ها رو میبینیم.
( این ریدایرکت با route انجام شده و چون کنار ngclick استفاده شده، متاسفانه قبل از اتمام آپدیت سبد (subscribe) خرید اتفاق می افته و باعث میشه دیتا در لحظه باز شدن Basket-list component نمایش داده نشه. باید درست بشه).
میتونیم تعدادش رو تغییر بدیم یا حذفش کنیم. موقع اضافه شدن آیتم تکراری باید تعداد آیتم فعلی تغییر کنه، نه که چندبار یک آیتم به سبد اضافه بشه.
تعداد آیتم های توی سبد خرید هم باید در header component معلوم باشه و با navigate between components چیزی از دست نره. همواره برای آپدیت سبد خرید یه شی basket به سرور می فرستیم و نه یک آیتم. که این کار رو سخت کرده بود. سمت سرور یه interface کلی برای repository داشتیم با متدهای update, delete ,... که توسط RedisRepo پیاده سازی شدند.
نصب پکیج redis- redis client for dotnet corre
https://www.nuget.org/packages/StackExchange.Redis/
(it's server would be the docker countainer)
نگاهی به مستنداتش:
https://stackexchange.github.io/StackExchange.Redis/Basics
توضیح کلی درمورد cache:
https://codeburst.io/redis-what-and-why-d52b6829813
https://jakeydocs.readthedocs.io/en/latest/performance/caching/distributed.html
نکته خیلی مهم درمورد hostname ها موقع کار با داکر:
Port 15672 is a port of rabbitmq management plugin web interface. When you are sending message to rabbit - you need to coect to different port (by default - 5672). So change your code to coect to that port and map it in docker via -p 5672:5672.
داشبرد rabbit (از image متفاوتی از من استفاده میکنه):
http://www.andyfrench.info/2017/08/quick-rabbitmq-using-docker.html
استفاده از subject در angular:
https://medium.com/instarem-engineering/subjects-in-angular-2-4-5-4e5986e38e47
تعریف singleton service در angular (همه service ها حتما singleton نیستند). در واقع:
It totally depends on component's lifecycle which provides the service.
They store their values as long as they live. When you navigate to somewhere outside of module that sets value on the service, you lose the value. Because you no longer have access to instance that has value set.
Services are singleton per provider. That means if you need a service/value globally, you need to make it singleton at global level. Providing AuthService at AppModule should solve your problem.
در واقع service های singleton در صفحه ای که در مرورگر باز میشه singleton هستند. یه صفحه جدید باز کنیم یه service جدید خواهیم داشت . بهتره دیتای لازم برای share در service در ctor سرویس از دیتابیس (یا کش سرور) گرفته بشه. (shared throughout your application means shared in the current browser window)
چرا با وجود service به استفاده از subject نیاز خواهیم داشت؟
دو مورد جدای آموزش هرکدوم:
https://jsonworld.com/demo/angular-8-communication-between-components-using-subject-and-observable
https://jsonworld.com/demo/share-data-between-angular-components-using-services
سرویس دیتایی رو در خودش نگه میداره (با توجه به scope و lifetime اش). اما موقع تغییر دیتا توسط یک component، اون یکی component با خبر نمیشه، مگر اینکه خودش explicitly دیتا رو مجدد درخواست کنه از سرویس.
برای اینکه به محض تغییر دیتا، همه کامپوننت هایی که دیتا بینشون share هست بفهمند، دیتا رو به صورت subject تعریف می کنیم. اونوقت در کامپوننت های مختلف می تونیم بهش subscribe() کنیم و موقع تغییر اون ها بفهمند.
for example when I add an item to basket on catalog detail component, the header component (which has been created once per app) must be notified. So it must subscribe to the "count" variable inside "sharedBasketService". This service is "Provided in root" so it's ctor will get called once per app. The count data is calcaulated at it's ctor from the item.length (The items are fetched from chache server). and it available to all. At any AddToBasket call, it's value is updated and so the current value to count is there in the header component.
There's a commom mistake that I tend to make: I must write code inside subscribe methed, not after it. That can cause a lot of semantic errors.
Another important thing was two way binding of quanitiy-> I must use ngModel when I'm getting data from view to component and vica versa.
+I think I forgot to write that, when coecting to a docker host with rabbitmq, redis or else, when using their dotnet client, there is no localhost. We must write the name of the service (provided in compose.yml file). That's how they find each other. Their names are translated to the IP addresses in the default network created by docker-compose up command.
برچسب:
نویسنده: سام بهرامی