如何使用 flutter bloc 模式通过分页加载数据列表?
How do I use flutter bloc pattern to load list of data with paging?
我在我的应用程序中使用了 flutter_bloc 并引用了这个 sample。现在当我 运行 我的应用程序时,它给我一个错误提示:
flutter: type 'MovieUninitialized' is not a subtype of type
'MovieLoaded' in type cast
我的区块包含三个文件:movie_state、movie_event 和 movie_bloc
movie_state.dart
import 'package:equatable/equatable.dart';
import 'package:movie_project/models/movie.dart';
abstract class MovieState extends Equatable {
MovieState([List props = const []]) : super(props);
}
class MovieUninitialized extends MovieState {
@override
String toString() => 'MovieUninitialized';
}
class MovieError extends MovieState {
@override
String toString() => 'MovieError';
}
class MovieLoaded extends MovieState {
final List<Movie> movies;
final bool hasReachedMax;
// Keeps track of the page to fetch the latest movies from the api
final latestMoviesPage;
MovieLoaded({
this.movies,
this.hasReachedMax,
this.latestMoviesPage,
}) : super([movies, hasReachedMax, latestMoviesPage]);
MovieLoaded copyWith({
List<Movie> movies,
bool hasReachedMax,
int latestMoviesPage,
}) {
return MovieLoaded(
movies: movies ?? this.movies,
hasReachedMax: hasReachedMax ?? this.hasReachedMax,
latestMoviesPage: this.latestMoviesPage,
);
}
@override
String toString() =>
'PostLoaded { posts: ${movies.length}, hasReachedMax: $hasReachedMax }';
}
movie_event.dart
import 'package:equatable/equatable.dart';
abstract class MovieEvent extends Equatable {}
class Fetch extends MovieEvent {
@override
String toString() => 'Fetch';
}
movie_bloc.dart
class MovieBloc extends Bloc<MovieEvent, MovieState> {
final MovieRepository movieRepository;
MovieBloc({@required this.movieRepository});
@override
Stream<MovieState> transform(
Stream<MovieEvent> events,
Stream<MovieState> Function(MovieEvent event) next,
) {
return super.transform(
(events as Observable<MovieEvent>).debounceTime(
Duration(milliseconds: 500),
),
next,
);
}
@override
MovieState get initialState => MovieUninitialized();
@override
Stream<MovieState> mapEventToState(MovieEvent event) async* {
if (event is Fetch && !_hasReachedMax(currentState)) {
try {
if (currentState is MovieUninitialized) {
final movies = await movieRepository.fetchMovies(1);
yield MovieLoaded(
movies: movies,
hasReachedMax: false,
latestMoviesPage:
(currentState as MovieLoaded).latestMoviesPage + 1,
);
return;
}
if (currentState is MovieLoaded) {
final movies = await movieRepository
.fetchMovies((currentState as MovieLoaded).latestMoviesPage);
yield movies.isEmpty
? (currentState as MovieLoaded).copyWith(hasReachedMax: true)
: MovieLoaded(
movies: (currentState as MovieLoaded).movies + movies,
hasReachedMax: false,
latestMoviesPage:
(currentState as MovieLoaded).latestMoviesPage + 1,
);
}
} catch (_) {
print(_);
yield MovieError();
}
}
}
bool _hasReachedMax(MovieState state) =>
state is MovieLoaded && state.hasReachedMax;
}
我需要递增 latestMoviesPage 直到它达到最大限制。如果我从我的 bloc 代码中删除 latestMoviesPage 问题得到解决,但我确实需要它来加载更多页面。
而不是
latestMoviesPage: (currentState as MovieLoaded).latestMoviesPage + 1,
我需要写:
latestMoviesPage: 2,
我在我的应用程序中使用了 flutter_bloc 并引用了这个 sample。现在当我 运行 我的应用程序时,它给我一个错误提示:
flutter: type 'MovieUninitialized' is not a subtype of type 'MovieLoaded' in type cast
我的区块包含三个文件:movie_state、movie_event 和 movie_bloc
movie_state.dart
import 'package:equatable/equatable.dart';
import 'package:movie_project/models/movie.dart';
abstract class MovieState extends Equatable {
MovieState([List props = const []]) : super(props);
}
class MovieUninitialized extends MovieState {
@override
String toString() => 'MovieUninitialized';
}
class MovieError extends MovieState {
@override
String toString() => 'MovieError';
}
class MovieLoaded extends MovieState {
final List<Movie> movies;
final bool hasReachedMax;
// Keeps track of the page to fetch the latest movies from the api
final latestMoviesPage;
MovieLoaded({
this.movies,
this.hasReachedMax,
this.latestMoviesPage,
}) : super([movies, hasReachedMax, latestMoviesPage]);
MovieLoaded copyWith({
List<Movie> movies,
bool hasReachedMax,
int latestMoviesPage,
}) {
return MovieLoaded(
movies: movies ?? this.movies,
hasReachedMax: hasReachedMax ?? this.hasReachedMax,
latestMoviesPage: this.latestMoviesPage,
);
}
@override
String toString() =>
'PostLoaded { posts: ${movies.length}, hasReachedMax: $hasReachedMax }';
}
movie_event.dart
import 'package:equatable/equatable.dart';
abstract class MovieEvent extends Equatable {}
class Fetch extends MovieEvent {
@override
String toString() => 'Fetch';
}
movie_bloc.dart
class MovieBloc extends Bloc<MovieEvent, MovieState> {
final MovieRepository movieRepository;
MovieBloc({@required this.movieRepository});
@override
Stream<MovieState> transform(
Stream<MovieEvent> events,
Stream<MovieState> Function(MovieEvent event) next,
) {
return super.transform(
(events as Observable<MovieEvent>).debounceTime(
Duration(milliseconds: 500),
),
next,
);
}
@override
MovieState get initialState => MovieUninitialized();
@override
Stream<MovieState> mapEventToState(MovieEvent event) async* {
if (event is Fetch && !_hasReachedMax(currentState)) {
try {
if (currentState is MovieUninitialized) {
final movies = await movieRepository.fetchMovies(1);
yield MovieLoaded(
movies: movies,
hasReachedMax: false,
latestMoviesPage:
(currentState as MovieLoaded).latestMoviesPage + 1,
);
return;
}
if (currentState is MovieLoaded) {
final movies = await movieRepository
.fetchMovies((currentState as MovieLoaded).latestMoviesPage);
yield movies.isEmpty
? (currentState as MovieLoaded).copyWith(hasReachedMax: true)
: MovieLoaded(
movies: (currentState as MovieLoaded).movies + movies,
hasReachedMax: false,
latestMoviesPage:
(currentState as MovieLoaded).latestMoviesPage + 1,
);
}
} catch (_) {
print(_);
yield MovieError();
}
}
}
bool _hasReachedMax(MovieState state) =>
state is MovieLoaded && state.hasReachedMax;
}
我需要递增 latestMoviesPage 直到它达到最大限制。如果我从我的 bloc 代码中删除 latestMoviesPage 问题得到解决,但我确实需要它来加载更多页面。
而不是
latestMoviesPage: (currentState as MovieLoaded).latestMoviesPage + 1,
我需要写:
latestMoviesPage: 2,