#flutter #flutter-layout #flutter-dependencies #flutter-web #flutter-test
Вопрос:
Я пытаюсь получить данные, я хочу получить данные о публикациях, используя блок в состоянии, данные готовы, я не буду извлекать их из api, данные готовы в списке сообщений, я просто хочу показать их в виджете с отслеживанием состояния, используя блок, как я могу это сделать, я новичок в блоке, я много искал, но все решения извлекают данные из api?
// это пост-класс
class Post {
final User user;
final String caption;
final String timeAgo;
final String imageUrl;
final int likes;
final int comments;
final int shares;
const Post({
required this.user,
required this.caption,
required this.timeAgo,
required this.imageUrl,
required this.likes,
required this.comments,
required this.shares,
});
}
// и это данные
final List<Post> posts =
[
Post(
user: currentUser,
caption: 'Check out these cool puppers',
timeAgo: '58m',
imageUrl: 'https://images.unsplash.com/photo-1525253086316-d0c936c814f8',
likes: 1202,
comments: 184,
shares: 96,
),
Post(
user: onlineUsers[5],
caption:
'Please enjoy this placeholder text: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
timeAgo: '3hr',
imageUrl: 'null',
likes: 683,
comments: 79,
shares: 18,
),
Post(
user: onlineUsers[4],
caption: 'This is a very good boi.',
timeAgo: '8hr',
imageUrl:
'https://images.unsplash.com/photo-1575535468632-345892291673?ixlib=rb-1.2.1amp;ixid=eyJhcHBfaWQiOjEyMDd9amp;auto=formatamp;fit=cropamp;w=634amp;q=80',
likes: 894,
comments: 201,
shares: 27,
),
Post(
user: onlineUsers[3],
caption: 'Adventure 🏔',
timeAgo: '15hr',
imageUrl:
'https://images.unsplash.com/photo-1573331519317-30b24326bb9a?ixlib=rb-1.2.1amp;ixid=eyJhcHBfaWQiOjEyMDd9amp;auto=formatamp;fit=cropamp;w=1350amp;q=80',
likes: 722,
comments: 183,
shares: 42,
),
Post(
user: onlineUsers[0],
caption:
'More placeholder text for the soul: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
timeAgo: '1d',
imageUrl: 'null',
likes: 482,
comments: 37,
shares: 9,
),
Post(
user: onlineUsers[9],
caption: 'A classic.',
timeAgo: '1d',
imageUrl:
'https://images.unsplash.com/reserve/OlxPGKgRUaX0E1hg3b3X_Dumbo.JPG?ixlib=rb-1.2.1amp;ixid=eyJhcHBfaWQiOjEyMDd9amp;auto=formatamp;fit=cropamp;w=634amp;q=80',
likes: 1523,
shares: 129,
comments: 301,
)
];
Ответ №1:
Для блока на самом деле существуют различные стратегии того, как вы можете публиковать и извлекать данные. Лучшая практика состоит в том, чтобы создать слой поставщиков данных и хранилищ, а затем, конечно, использовать логический уровень для обработки данных и получения состояний. Для начального шага вы можете использовать что-то вроде расширения блока, доступного в VSCode от Felix. Просто щелкните правой кнопкой мыши на папке lib, и там вы увидите новый блок (после установки расширения). Как только вы закончите с этим, вы можете создать другой уровень, называемый поставщиком данных, в котором вы можете настроить свой API так, как вам нравится (например, с помощью http или dio).
Примером поставщика данных может быть.
что-то_репо.дротик
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class SomethingApiClient {
final http.Client? httpClient;
SomethingApiClient({
@required this.httpClient,
}) : assert(httpClient != null);
Future<SomthingModel> fetchSomething() async {
final url = '${baseUrl}api/v1/whatyouwannacall';
final response = await http.get(Uri.parse(url), headers: {
//any header that is required.
});
if (response.statusCode != 200) {
throw new Exception('error getting products');
}
return somthingFromJson(response.body);
}
}
затем вы можете превратить какое-то событие в события.dart
Это также поможет вам отправлять данные в блок, а также при работе с логикой и выводом.
Например, для
Я передаю только строку, но вы можете передать модель, если потребуется, как вы сказали.
some_event.дротик
part of 'products_bloc.dart';
abstract class ProductsEvent extends Equatable {
const ProductsEvent();
}
class FetchProducts extends ProductsEvent {
final String? product;
const FetchProducts({this.product});
@override
List<Object> get props => [];
}
Затем возникают состояния, например, если блок должен выдать ошибку или успех, основываясь на вашем сценарии.
Я использую equatable для сравнения значений, чтобы исключить ненужные сборки пользовательского интерфейса.
part of 'products_bloc.dart';
abstract class ProductsState extends Equatable {
const ProductsState();
@override
List<Object> get props => [];
}
class ProductsInitial extends ProductsState {}
class ProductsEmpty extends ProductsState {}
class ProductsLoading extends ProductsState {
get products => null;
}
class ProductsLoaded extends ProductsState {
final Products? products;
const ProductsLoaded({this.products}) : assert(products != null);
@override
List<Object> get props => [products!];
}
class ProductsError extends ProductsState {}
И, наконец, тогда вам придется написать некоторый код блока для реализации логики.
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
part 'dummy_bloc_event.dart';
part 'dummy_bloc_state.dart';
class DummyBlocBloc extends Bloc<DummyBlocEvent, DummyBlocState> {
DummyBlocBloc() : super(DummyBlocInitial());
@override
Stream<DummyBlocState> mapEventToState(
DummyBlocEvent event,
) async* {
if(event is YourDesiredEvent)
{
yield DummyLoadingState();
try{
//try your api here
final DummyModel products = await repository!.fetchdummy();
yield ProductsLoaded(products: products);
}
catch (error, stacktrace) {
print('$error $stacktrace');
yield DummyError();
}
}
}
}
Существует также ограничение, которое вам нужно будет установить при использовании blocProvider для инициализации, как в generatedroutes.
Что-то вроде этого
import 'dart:async';
import 'package:kind_app_admin/APImodels/categoriesModel.dart';
import 'package:kind_app_admin/DataProviders/categoriesDataProvider.dart';
import 'package:meta/meta.dart';
class DummyRepository {
final DummyApiClient? dummyApiClient;
DummyRepository({@required this.dummyApiClient})
: assert(dummyApiClient != null);
Future<Categories> fetchDummy() async {
return await dummyApiClient!.fetchDummy();
}
}
Вы можете инициализировать этот репозиторий в маршрутах, созданных приложением, или там, где вы хотите инициализировать, например
final ProductUpdateRepository _productUpdateRepository =
ProductUpdateRepository(
productUpdateApiClient: ProductUpdateApiClient(
httpClient: http.Client(),
),
);
А затем используйте поставщика блоков с экземпляром или вы можете использовать мультиблоковые провайдеры, если хотите предоставить более одного экземпляра блока.
BlocProvider(
create: (context) =>
DummyBloc(dummyRepository: _dummyRepository),
),
child: SomeScreen(),