Trong phát triển ứng dụng Flutter, việc quản lý trạng thái là một vấn đề quan trọng mà các nhà phát triển thường phải đối mặt. Hai trong số các mô hình quản lý trạng thái phổ biến là ScopedModel và BLoC Pattern. Bài viết này sẽ đi sâu vào hai mô hình này, giúp bạn hiểu rõ hơn về cách thức hoạt động cũng như cách sử dụng chúng trong ứng dụng Flutter.
ScopedModel là một thư viện quản lý trạng thái đơn giản, giúp các widget trong Flutter chia sẻ và cập nhật trạng thái mà không cần phải sử dụng các cơ chế phức tạp.
ScopedModel cho phép bạn định nghĩa một model (mô hình) có thể được chia sẻ giữa nhiều widget mà không cần phải truyền dữ liệu qua constructor. Các widget có thể lắng nghe sự thay đổi trong model và tự động cập nhật khi có sự thay đổi.
Để sử dụng ScopedModel, trước tiên bạn cần thêm nó vào file pubspec.yaml
:
dependencies: scoped_model: ^1.0.1
Sau đó, bạn có thể định nghĩa model của mình. Ví dụ:
import 'package:scoped_model/scoped_model.dart'; class CounterModel extends Model { int _count = 0; int get count => _count; void increment() { _count++; notifyListeners(); // Thông báo cho các widget lắng nghe rằng dữ liệu đã thay đổi } }
Để sử dụng model trong widget của bạn, bạn cần bao bọc widget gốc trong ScopedModel
:
import 'package:flutter/material.dart'; import 'package:scoped_model/scoped_model.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return ScopedModel<CounterModel>( model: CounterModel(), child: MaterialApp( home: Scaffold( appBar: AppBar(title: Text('ScopedModel Example')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ScopedModelDescendant<CounterModel>( builder: (context, child, model) { return Text('Count: ${model.count}'); }, ), ElevatedButton( onPressed: () { ScopedModel.of<CounterModel>(context).increment(); }, child: Text('Increment'), ), ], ), ), ), ), ); } }
BLoC (Business Logic Component) là một mô hình kiến trúc giúp tách biệt logic kinh doanh khỏi giao diện người dùng, cho phép dễ dàng kiểm thử và tái sử dụng mã. BLoC sử dụng các Stream để quản lý trạng thái.
Mô hình BLoC giúp bạn quản lý trạng thái ứng dụng bằng cách sử dụng các stream để giao tiếp giữa UI và logic kinh doanh. UI sẽ gửi sự kiện đến BLoC thông qua Sink và nhận trạng thái cập nhật thông qua Stream.
Để sử dụng BLoC, bạn có thể cài đặt thư viện flutter_bloc
bằng cách thêm vào file pubspec.yaml
:
dependencies: flutter_bloc: ^8.0.1
Đầu tiên, bạn cần tạo một class BLoC. Ví dụ:
import 'package:flutter_bloc/flutter_bloc.dart'; // Các sự kiện cho BLoC abstract class CounterEvent {} class Increment extends CounterEvent {} // Trạng thái cho BLoC abstract class CounterState {} class CounterInitial extends CounterState { final int count; CounterInitial(this.count); } // BLoC cho Counter class CounterBloc extends Bloc<CounterEvent, CounterState> { CounterBloc() : super(CounterInitial(0)); @override Stream<CounterState> mapEventToState(CounterEvent event) async* { if (event is Increment) { final currentState = state as CounterInitial; yield CounterInitial(currentState.count + 1); } } }
Để sử dụng BLoC trong widget của bạn, bạn cần sử dụng BlocProvider
để cung cấp BLoC cho widget:
import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: BlocProvider( create: (context) => CounterBloc(), child: CounterPage(), ), ); } } class CounterPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('BLoC Example')), body: Center( child: BlocBuilder<CounterBloc, CounterState>( builder: (context, state) { if (state is CounterInitial) { return Text('Count: ${state.count}'); } return CircularProgressIndicator(); }, ), ), floatingActionButton: FloatingActionButton( onPressed: () { BlocProvider.of<CounterBloc>(context).add(Increment()); }, child: Icon(Icons.add), ), ); } }
Cả ScopedModel và BLoC Pattern đều là những lựa chọn mạnh mẽ cho việc quản lý trạng thái trong Flutter. Lựa chọn mô hình nào phụ thuộc vào quy mô và độ phức tạp của ứng dụng của bạn. Hy vọng rằng bài viết này đã giúp bạn hiểu rõ hơn về hai mô hình này và cách áp dụng chúng trong ứng dụng của mình.