在 flutter BLoC 中更改 placeID 后数据未更新
Data not being updated after change the placeID in flutter BLoC
我正在与 BLoC.I 进行一个项目,已经做了一些 类 来更新数据。
一旦您通过 placeID,数据就会到来。
但是一旦您第一次通过 PlaceID,它就会更新数据和小部件。
但是一旦我通过新的 placeID,旧数据就不会更新。它显示旧数据。
所有代码文件:
RestaurantDetailBloc.dart
class RestaurantDetailBloc extends Bloc<RestaurantDetailEvent, RestaurantDetailState> {
static final RestaurantDetailBloc _restaurantDetailBlocSingleton = new RestaurantDetailBloc._internal();
factory RestaurantDetailBloc() {
return _restaurantDetailBlocSingleton;
}
RestaurantDetailBloc._internal();
RestaurantDetailState get initialState => new UnRestaurantDetailState();
@override
Stream<RestaurantDetailState> mapEventToState(
RestaurantDetailEvent event,
) async* {
try {
yield await event.applyAsync(currentState: currentState, bloc: this);
} catch (_, stackTrace) {
print('$_ $stackTrace');
yield currentState;
}
}
}
LoadRestaurantDetailEvent.dart
@immutable
abstract class RestaurantDetailEvent {
Future<RestaurantDetailState> applyAsync(
{RestaurantDetailState currentState, RestaurantDetailBloc bloc});
final RestaurantDetailProvider _provider = RestaurantDetailProvider();
}
class LoadRestaurantDetailEvent extends RestaurantDetailEvent {
@override
String toString() => 'LoadRestaurantDetailEvent';
String placeID;
LoadRestaurantDetailEvent({Key key,this.placeID});
@override
Future<RestaurantDetailState> applyAsync(
{RestaurantDetailState currentState, RestaurantDetailBloc bloc}) async {
try {
await Future.delayed(new Duration(seconds: 2));
var component = await _provider.getRestaurantReview(placeID);
print(component);
return new InRestaurantDetailState(component);
} catch (_, stackTrace) {
print('$_ $stackTrace');
return new ErrorRestaurantDetailState(_?.toString());
}
}
}
RestaurantDetailPage.dart
class RestaurantDetailPage extends StatelessWidget {
static const String routeName = "/restaurantDetail";
final String imageURL;
final String placeID;
const RestaurantDetailPage({Key key, this.imageURL,this.placeID}) : super(key: key);
@override
Widget build(BuildContext context) {
var _restaurantDetailBloc = new RestaurantDetailBloc();
return new RestaurantDetailScreen(restaurantDetailBloc: _restaurantDetailBloc,imageUrl: this.imageURL,placeId: this.placeID,);
}
}
RestaurantDetailProvider.dart
class RestaurantDetailProvider {
String getBaseUrl(String placeID){
final urlBase = "https://maps.googleapis.com/maps/api/place/details/json?placeid=$placeID&key=xxxxxxxxxxxxxGooglePlaceKey";
return urlBase;
}
Future<void> loadAsync(String token) async {
/// write from keystore/keychain
await Future.delayed(new Duration(seconds: 2));
}
Future<void> saveAsync(String token) async {
/// write from keystore/keychain
await Future.delayed(new Duration(seconds: 2));
}
Future<Map<String, dynamic>> getRestaurantReview(String placeId)async{
var response = await http.get(getBaseUrl(placeId));
RestaurantReviews reviews = RestaurantReviews();
if(response.statusCode == 200){
var decodedJson = jsonDecode(response.body);
print(decodedJson);
//reviews.result = decodedJson['result'];
return decodedJson;
}
else{
}
}
}
InRestaurantDetailState.dart
@immutable
abstract class RestaurantDetailState extends Equatable {
RestaurantDetailState([Iterable props]) : super(props);
/// Copy object for use in action
RestaurantDetailState getStateCopy();
}
/// UnInitialized
class UnRestaurantDetailState extends RestaurantDetailState {
@override
String toString() => 'UnRestaurantDetailState';
@override
RestaurantDetailState getStateCopy() {
return UnRestaurantDetailState();
}
}
class InRestaurantDetailState extends RestaurantDetailState {
final resReview;
InRestaurantDetailState(this.resReview);
@override
String toString() => 'InRestaurantDetailState';
@override
RestaurantDetailState getStateCopy() {
return InRestaurantDetailState(resReview);
}
}
class ErrorRestaurantDetailState extends RestaurantDetailState {
final String errorMessage;
ErrorRestaurantDetailState(this.errorMessage);
@override
String toString() => 'ErrorRestaurantDetailState';
@override
RestaurantDetailState getStateCopy() {
return ErrorRestaurantDetailState(this.errorMessage);
}
}
RestaurantDetailScreenState.dart
class RestaurantDetailScreen extends StatefulWidget {
const RestaurantDetailScreen({
Key key,
@required RestaurantDetailBloc restaurantDetailBloc,
this.imageUrl, this.placeId,
}) : _restaurantDetailBloc = restaurantDetailBloc,
super(key: key);
final RestaurantDetailBloc _restaurantDetailBloc;
final String imageUrl;
final String placeId;
@override
RestaurantDetailScreenState createState() {
return new RestaurantDetailScreenState(_restaurantDetailBloc, imageUrl,placeId);
}
}
class RestaurantDetailScreenState extends State<RestaurantDetailScreen> {
final RestaurantDetailBloc _restaurantDetailBloc;
final String imageUrl;
final String placeId;
RestaurantDetailScreenState(this._restaurantDetailBloc, this.imageUrl,this.placeId);
@override
void initState() {
super.initState();
this._restaurantDetailBloc.dispatch(LoadRestaurantDetailEvent(placeID:placeId));
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
final width = MediaQuery.of(context).size.width;
final height = MediaQuery.of(context).size.height;
return BlocBuilder<RestaurantDetailBloc, RestaurantDetailState>(
bloc: widget._restaurantDetailBloc,
builder: (
BuildContext context,
var currentState,
) {
if (currentState is UnRestaurantDetailState) {
return MaterialApp(
home: new Scaffold(
body: new Container(
color: Colors.white,
child: Center(
child: CircularProgressIndicator(),
),
),
));
}
if (currentState is ErrorRestaurantDetailState) {
return new Container(
child: new Center(
child: new Text(currentState.errorMessage ?? 'Error'),
));
}
if (currentState is InRestaurantDetailState) {
var resList = currentState.resReview;
print(resList);
return MaterialApp(
home: new Scaffold(
)
);
}
请帮帮我 guys.I 花了一整天。
提前谢谢你。
您需要将数据传递给父class进行比较。这就是我们使用 equatable 的原因。进行这些更改,它应该会起作用。如果没有,请告诉我。
class InRestaurantDetailState extends RestaurantDetailState {
final resReview;
//You need to change this line to
InRestaurantDetailState(this.resReview):super([resReview]);
@override
String toString() => 'InRestaurantDetailState';
@override
RestaurantDetailState getStateCopy() {
return InRestaurantDetailState(resReview);
}
}
我正在与 BLoC.I 进行一个项目,已经做了一些 类 来更新数据。 一旦您通过 placeID,数据就会到来。 但是一旦您第一次通过 PlaceID,它就会更新数据和小部件。 但是一旦我通过新的 placeID,旧数据就不会更新。它显示旧数据。
所有代码文件:
RestaurantDetailBloc.dart
class RestaurantDetailBloc extends Bloc<RestaurantDetailEvent, RestaurantDetailState> {
static final RestaurantDetailBloc _restaurantDetailBlocSingleton = new RestaurantDetailBloc._internal();
factory RestaurantDetailBloc() {
return _restaurantDetailBlocSingleton;
}
RestaurantDetailBloc._internal();
RestaurantDetailState get initialState => new UnRestaurantDetailState();
@override
Stream<RestaurantDetailState> mapEventToState(
RestaurantDetailEvent event,
) async* {
try {
yield await event.applyAsync(currentState: currentState, bloc: this);
} catch (_, stackTrace) {
print('$_ $stackTrace');
yield currentState;
}
}
}
LoadRestaurantDetailEvent.dart
@immutable
abstract class RestaurantDetailEvent {
Future<RestaurantDetailState> applyAsync(
{RestaurantDetailState currentState, RestaurantDetailBloc bloc});
final RestaurantDetailProvider _provider = RestaurantDetailProvider();
}
class LoadRestaurantDetailEvent extends RestaurantDetailEvent {
@override
String toString() => 'LoadRestaurantDetailEvent';
String placeID;
LoadRestaurantDetailEvent({Key key,this.placeID});
@override
Future<RestaurantDetailState> applyAsync(
{RestaurantDetailState currentState, RestaurantDetailBloc bloc}) async {
try {
await Future.delayed(new Duration(seconds: 2));
var component = await _provider.getRestaurantReview(placeID);
print(component);
return new InRestaurantDetailState(component);
} catch (_, stackTrace) {
print('$_ $stackTrace');
return new ErrorRestaurantDetailState(_?.toString());
}
}
}
RestaurantDetailPage.dart
class RestaurantDetailPage extends StatelessWidget {
static const String routeName = "/restaurantDetail";
final String imageURL;
final String placeID;
const RestaurantDetailPage({Key key, this.imageURL,this.placeID}) : super(key: key);
@override
Widget build(BuildContext context) {
var _restaurantDetailBloc = new RestaurantDetailBloc();
return new RestaurantDetailScreen(restaurantDetailBloc: _restaurantDetailBloc,imageUrl: this.imageURL,placeId: this.placeID,);
}
}
RestaurantDetailProvider.dart
class RestaurantDetailProvider {
String getBaseUrl(String placeID){
final urlBase = "https://maps.googleapis.com/maps/api/place/details/json?placeid=$placeID&key=xxxxxxxxxxxxxGooglePlaceKey";
return urlBase;
}
Future<void> loadAsync(String token) async {
/// write from keystore/keychain
await Future.delayed(new Duration(seconds: 2));
}
Future<void> saveAsync(String token) async {
/// write from keystore/keychain
await Future.delayed(new Duration(seconds: 2));
}
Future<Map<String, dynamic>> getRestaurantReview(String placeId)async{
var response = await http.get(getBaseUrl(placeId));
RestaurantReviews reviews = RestaurantReviews();
if(response.statusCode == 200){
var decodedJson = jsonDecode(response.body);
print(decodedJson);
//reviews.result = decodedJson['result'];
return decodedJson;
}
else{
}
}
}
InRestaurantDetailState.dart
@immutable
abstract class RestaurantDetailState extends Equatable {
RestaurantDetailState([Iterable props]) : super(props);
/// Copy object for use in action
RestaurantDetailState getStateCopy();
}
/// UnInitialized
class UnRestaurantDetailState extends RestaurantDetailState {
@override
String toString() => 'UnRestaurantDetailState';
@override
RestaurantDetailState getStateCopy() {
return UnRestaurantDetailState();
}
}
class InRestaurantDetailState extends RestaurantDetailState {
final resReview;
InRestaurantDetailState(this.resReview);
@override
String toString() => 'InRestaurantDetailState';
@override
RestaurantDetailState getStateCopy() {
return InRestaurantDetailState(resReview);
}
}
class ErrorRestaurantDetailState extends RestaurantDetailState {
final String errorMessage;
ErrorRestaurantDetailState(this.errorMessage);
@override
String toString() => 'ErrorRestaurantDetailState';
@override
RestaurantDetailState getStateCopy() {
return ErrorRestaurantDetailState(this.errorMessage);
}
}
RestaurantDetailScreenState.dart
class RestaurantDetailScreen extends StatefulWidget {
const RestaurantDetailScreen({
Key key,
@required RestaurantDetailBloc restaurantDetailBloc,
this.imageUrl, this.placeId,
}) : _restaurantDetailBloc = restaurantDetailBloc,
super(key: key);
final RestaurantDetailBloc _restaurantDetailBloc;
final String imageUrl;
final String placeId;
@override
RestaurantDetailScreenState createState() {
return new RestaurantDetailScreenState(_restaurantDetailBloc, imageUrl,placeId);
}
}
class RestaurantDetailScreenState extends State<RestaurantDetailScreen> {
final RestaurantDetailBloc _restaurantDetailBloc;
final String imageUrl;
final String placeId;
RestaurantDetailScreenState(this._restaurantDetailBloc, this.imageUrl,this.placeId);
@override
void initState() {
super.initState();
this._restaurantDetailBloc.dispatch(LoadRestaurantDetailEvent(placeID:placeId));
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
final width = MediaQuery.of(context).size.width;
final height = MediaQuery.of(context).size.height;
return BlocBuilder<RestaurantDetailBloc, RestaurantDetailState>(
bloc: widget._restaurantDetailBloc,
builder: (
BuildContext context,
var currentState,
) {
if (currentState is UnRestaurantDetailState) {
return MaterialApp(
home: new Scaffold(
body: new Container(
color: Colors.white,
child: Center(
child: CircularProgressIndicator(),
),
),
));
}
if (currentState is ErrorRestaurantDetailState) {
return new Container(
child: new Center(
child: new Text(currentState.errorMessage ?? 'Error'),
));
}
if (currentState is InRestaurantDetailState) {
var resList = currentState.resReview;
print(resList);
return MaterialApp(
home: new Scaffold(
)
);
}
请帮帮我 guys.I 花了一整天。 提前谢谢你。
您需要将数据传递给父class进行比较。这就是我们使用 equatable 的原因。进行这些更改,它应该会起作用。如果没有,请告诉我。
class InRestaurantDetailState extends RestaurantDetailState {
final resReview;
//You need to change this line to
InRestaurantDetailState(this.resReview):super([resReview]);
@override
String toString() => 'InRestaurantDetailState';
@override
RestaurantDetailState getStateCopy() {
return InRestaurantDetailState(resReview);
}
}