صفحه اصلی >> بلاگ >> State Management در Flutter با پکیج Provider

State Management در Flutter با پکیج Provider

دسته:فلاتر تاریخ انتشار: 8 فوریه 2021 ایمان رضایی

بعد از خواندن کامل این مقاله ، شما دید واضحی در مورد اینکه چرا ما از راه حل های State Management استفاده می کنیم و تا چه حد برای اپلیکیشن مفید هستند ، پیدا خواهید کرد. همچنین با نصب Provider  و پیاده سازی در کد ، آشنا خواهید شد. برای اینکار حتماً مقاله را کامل بخوانید!

 

State و State Management چیست؟

State  به عنوان داده ای تعریف می شود که رابط کاربری را تحت تأثیر قرار می دهد و می تواند با گذشت زمان تغییر کند. بنابراین ، رابط کاربری در اینجا می تواند به عنوان عملکرد داده های شما توصیف شود.

دو حالت اصلی وجود دارد:

  • App Wide State: این نوع State  بر کل برنامه تأثیر می گذارد ، به عنوان مثال ، اگر بخواهیم احراز هویت کاربر را بررسی کنیم. اگر کاربر احراز هویت نشده باشد ، باید صفحه login/signup یا صفحه محصولات را برای یک برنامه خرید آنلاین نشان دهیم.
  • Local State: این نوع State فقط بر روی ابزارک ها تأثیر می گذارد ، به عنوان مثال ، اگر بخواهیم چرخنده بارگذاری را اضافه کنیم تا زمانی که محصولات در فروشگاه آنلاین نشان داده شوند.

State Management به عنوان مدیریت حات یک یا چند کنترل رابط کاربری تعریف می شود. به عنوان مثال ، من روی یک دکمه کلیک می کنم و آن دکمه موضوع برنامه را تغییر می دهد. این کار از طریق مدیریت حالت انجام می شود. اکنون سوال اصلی مطرح می شود ، چرا ما به مدیریت حالت احتیاج داریم؟ بگذارید در مورد آن بدانیم!

چرا به مدیریت حالت احتیاج داریم؟

  1. هرچه برنامه بزرگتر و پیچیده تر می شود ، انتقال داده ها از طریق سازندگان(constructors) می تواند دست و پا گیر و دشوار باشد. به عنوان مثال ، من یک صفحه ورود به سیستم دارم و به نام کاربر در صفحه تنظیمات نیاز دارم. برای این منظور ، من باید نام کاربر را از طریق سازنده به صفحه اصلی منتقل کنم که سپس نام را از طریق سازنده دوباره به صفحه تنظیمات می فرستد که با بزرگتر شدن برنامه خسته کننده می شود و صفحه های بیشتری به دست می آوریم.
  2. بازسازی های غیرضروری کل برنامه یا قطعات اصلی برنامه وجود دارد و حتی کمبود حافظه که باید مراقبت شود.

اکنون ، ما می دانیم که چرا به مدیریت حالت نیاز داریم اما به کدام یک در فلاتر نیاز داریم؟ چندین راه حل مدیریت حالت وجود دارد. بیایید مروری بر آنها داشته باشیم.

 

راه حل های مدیریت حالت در فلاتر:

  • Provider
  • Inherited Widget
  • Redux
  • BLoC
  • MobX
  • GetIt
  • RiverPod

من شخصاً Provider را به همه این موارد ترجیح می دهم و ما به جزئیات پکیج Provider در این مقاله خواهیم پرداخت.

Provider از Inherited Widget به طور غیرمستقیم برای ایجاد کانال ارتباط مستقیم بین ویجت و ارائه دهنده داده (کانتینر) استفاده می کند که به ویجت مختلف متصل است و در زیر نمودار نحوه کارکرد ویجت وراثت نمایش داده شده است.

 

Provider Package

provider به گونه ای کار می کند که گویی یک ارائه دهنده مرکزی داده مرکزی (کانتینر) دارید که باید آن را به ابزارک خود ضمیمه کنید. بعد از اینکه ارائه دهنده را به ابزارک متصل کردید ، همه ابزارکهای فرزند می توانند به آن ارائه دهنده گوش دهند ، نه اینکه از سازنده استفاده کنید اما

استفاده از of(context). ارائه دهنده باید با کمک کلاس تعریف شود. New Provider بر اساس تعریف کلاس ساخته شده است که به عنوان مدل نامیده می شود. مزیت استفاده از Provider این است که باعث می شود فقط وقتی تغییر حالت می دهد متد build() اجرا شود ، یعنی هر وقت داده در ارائه دهنده داده (کانتینر) تغییر می کند ، فقط در این صورت UI نیز به روز می شود.

مدلهایی که در Provider استفاده می شوند اساساً اشیایی هستند که با هم مخلوط شده اند. مخلوط با استفاده از کلمه کلیدی * همراه با * و به دنبال آن نام مخلوط اضافه می شود. مخلوط کردن شبیه کلمه کلیدی * گسترش دهنده * است (وراثت). تفاوت اصلی این است که شما برخی از خصوصیات را ادغام می کنید یا برخی از متدها را در کلاس موجود اضافه می کنید اما کلاس خود را به نمونه ای از آن کلاس بر نمی گردانید.

نحوه نصب

به وب سایت Pub Dev  بروید و به برگه نصب بروید و کد را به وابستگی ها اضافه کنید.

 

کد با Provider

class Products with ChangeNotifier {}

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

ChangeNotifier نام مخلوطی است که مربوط به inherited widget  است که توسط Provider در پشت صحنه استفاده می شود. لزوماً نباید از ChangeNotifierProvider در ریشه درخت ابزارک استفاده کنید ، فقط باید آن را در بالاترین سطح ابزارک هایی که به داده های درخت عناصر نیاز دارند اضافه کنید.

(جزئیات بیشتر در مورد این در زیر)

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

 

انواع Provider

  • ProxyProvider
  • ChangeNotifierProvider
  • Provider
  • ListenableProvider
  • StreamProvider
  • MultiProvider

و بیشتر..

ما با ChangeNotifierProvider کار خواهیم کرد ..

شی Product در زیر استفاده می شود

ChangeNotifier

 

class Products with ChangeNotifier {
 List<Product> _items = {// add some data..};
 List<Product> get items {
  return [..._items];
 }void findById(String newId) {
  _items.firstWhere((prod) => prod.id == newId); // This is how we get loaded Products
 }void addProduct(Product newProduct) {
  _items.add(newProduct);
  notifyListeners();
 }
}

 

این مدلی به نام Products است. برای یادآوری ، ChangeNotifier مخلوطی است که توسط بسته Provider ارائه شده است و توابع ساخته شده مانند notifyListeners را به ما می دهد. برای توضیح کد ، ما یک کپی از آیتم ها را با استفاده از اپراتور spread برمی گردانیم تا نتوانیم مستقیماً آیتم ها را از هرجای دیگر برنامه ویرایش کنیم ، اگر این کار را انجام دهیم نمی توانیم  notifyListeners()  را فراخوانی کنیم زیرا فقط این کار را می توانیم از داخل کلاس انجام دهیم و بازسازی ویجت انجام نمی شود به درستی زیرا ابزارک ها از تغییر اطلاع ندارند.

 

ChangeNotifierProvider

 

return ChangeNotifierProvider(
create: (ctx) => Products(),
//If you use provider version 3.0.0 then function you have to call is builder. For 4.0.0 and above function is create.
child: ...
);

 

شما باید ChangeNotifierProvider را در ویجت والد ویجت (ها) ای که می خواهید از آن اطلاعات بشنوید قرار دهید.

Provider.of

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

Provider.of<T>(context);

Provider به ما اجازه می دهد تا بین یکی از کلاسهای ارائه شده ارتباط برقرار کنیم.

T در اینجا به نوع داده ای که می خواهید اشاره دارد (نوع عمومی داده)

برای کد ما ، می توانیم از موارد زیر استفاده کنیم:

Provider.of<Products>(context);

 

اینگونه است که شما از طریق ابزارک به کلاس گوش می دهید. Provider اکنون وارد کلاس والد ویجت می شود و بررسی می کند که آیا توسط هر یک از ارائه دهندگان پوشش داده شده باشد (ChangeNotifierProvider در پرونده ما).

 

موضوع و قرارداد های مرتبط با منطق

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

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

Provider.of<Products>(context).findById("AnyIdDuh");

 

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

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

Provider.of<Products>(context, listen:false).findById("AnyIdDuh");

 

جایگزین برای Provider.of

Consumer گزینه دیگری برای Provider.of است که توسط پکیج Provider نیز ارائه شده است. به طور خاص در اطراف ابزارک فرزند قرار داده شده است که باید در ویجت ساخته شود. به عنوان مثال ، من یک آیکون قلب در یک شبکه دارم ، که باید با فشار دادن آن رنگ آن را تغییر دهد و هیچ چیز دیگری نباید تغییر کند بنابراین هیچ چیز نباید به ارائه دهنده (container) گوش دهد. به جای بازسازی کل ویجت که دارای نام و قیمت محصول نیز هست ، می توانم Consumer را در اطراف ویجت قرار دهم ، در مثال من ، IconButton. کد زیر را برای وضوح بررسی کنید.

 

return Consumer<T>(
builder: (ctx, instanceOfT, child) => IconButton(...),
child: Text("This text will never change."),
);

 

اگر شما از Provider.of در این مورد استفاده می کردید ، این روش باعث ساخت دوباره کل متد و ایجاد مشکلات جزئی در عملکرد می شد.

در اینجا ، T به نوع عمومی اشاره دارد که می تواند هر نوع داده ای باشد اما وقتی از دادهType / Models استفاده می کنیم که از قبل مانند String وجود ندارد ، معنی بیشتری دارد.

بنابراین ، این پکیج  Provider بود - توضیح ، نصب و کد! امیدوارم دانش کافی برای پیاده سازی در کد خود داشته باشید و به اندازه کافی با آنها کار کنید!


n0
n276

برای ثبت نظر باید وارد سایت شوید یا ثبت نام نمایید.


نظر شما با موفقیت در سیستم ثبت گردید.