找不到正确的提供商<电影>在此MyApp小部件上方

发布于 2025-01-19 14:54:25 字数 3722 浏览 0 评论 0原文

因此,我在一个应用程序中使用集团和提供商软件包。 在我的“ MovieProvider.dart”中,我正在从API中获取一些数据,这些数据是在App首次打开时返回JSON的。如何从main.dart中的多个载体中访问(上下文)?基本上,我想访问列表电影的同一实例,但不知道如何。

我遇到的错误:


错误:无法在此myapp小部件上方找到正确的提供商

,因为您使用了不包括提供商的buildContext 您的选择。


代码: main.dart

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider.value(
          value: Movies(),
        ),
        Provider<SwipeBloc>(create: (_) {
          SwipeBloc()
            ..add(
              LoadMoviesEvent(
                movies: context.read<Movies>().movies,
              ),
            );
        }),
        ChangeNotifierProvider.value(
          value: User(),
        ),
        ChangeNotifierProvider.value(
          value: Auth(),
        ),
      ],
      child: ...
  }
}

Movie_provider.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:movies_recomendations/constants.dart';
import 'package:http/http.dart' as http;

import './single_movie_provider.dart';

class Movies with ChangeNotifier {
  String plotText = "";

  List<Movie> _movies = [];

  List<Movie> get movies {
    return <Movie>[..._movies];
  }

  .....

  Future<void> fetchAndSetMovies() async {
    const url = 'http://192.168.1.142:8000/Desktop/textData.json';

    try {
      final response = await http.get(
        Uri.parse(url),
      );
      String source = Utf8Decoder().convert(response.bodyBytes);

      final extractedData =
          List<Map<String, dynamic>>.from(json.decode(source));
      final List<Movie> loadedMovies = [];

      extractedData.forEach(
        ((movieInfo) => {
              loadedMovies.add(Movie(
                id: movieInfo['id'],
                age: 12,
                countries: List<String>.from(movieInfo['country']),
                description: movieInfo['descriprion'],
                frames: movieInfo['frames'],
                genre: movieInfo['genre'],
                poster: movieInfo['poster'],
                premiereWorld: movieInfo['date'].toString(),
                ratingIMDb: movieInfo['ratingIMDb'],
                ratingKinopoisk: movieInfo['ratingKinopoisk'],
                title: movieInfo['title'][1],
                ifSeries: movieInfo['ifSeries'],
                dateTo: movieInfo['dateTo'].toString(),
                isFavourite: true,
                seasons: movieInfo['seasons'],
              )),
            }),
      );
      _movies = loadedMovies;
      notifyListeners();
    } on Exception catch (e) {
      print('error');
      print(e.toString());
    }
  }
}

swipe_event.dart.dart

part of 'swipe_block.dart';

abstract class SwipeEvent extends Equatable {
  const SwipeEvent();

  @override
  List<Object> get props => [];
}

class LoadMoviesEvent extends SwipeEvent {
  final List<Movie> movies ;

  LoadMoviesEvent({
    required this.movies,
  });

  @override
  List<Object> get props => [movies];
}

class SwipeLeftEvent extends SwipeEvent {
  final Movie movie;

  SwipeLeftEvent({
    required this.movie,
  });

  @override
  List<Object> get props => [movie];
}

class SwipeRightEvent extends SwipeEvent {
  final Movie movie;

  SwipeRightEvent({
    required this.movie,
  });

  @override
  List<Object> get props => [movie];
}

So, I'm using BLoC and Provider packages in one app.
In my 'moviesprovider.dart' I am fetching some data from my API which returns a json, when app is opening first time. How can I get access to Provider.of(context) from main.dart in MultiProvider? Basically, I want to get access to the same instance of List movies, but don't know how.

The error I'm getting:


Error: Could not find the correct Provider above this MyApp Widget

This happens because you used a BuildContext that does not include the provider
of your choice.


Code:
Main.dart

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider.value(
          value: Movies(),
        ),
        Provider<SwipeBloc>(create: (_) {
          SwipeBloc()
            ..add(
              LoadMoviesEvent(
                movies: context.read<Movies>().movies,
              ),
            );
        }),
        ChangeNotifierProvider.value(
          value: User(),
        ),
        ChangeNotifierProvider.value(
          value: Auth(),
        ),
      ],
      child: ...
  }
}

movies_provider.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:movies_recomendations/constants.dart';
import 'package:http/http.dart' as http;

import './single_movie_provider.dart';

class Movies with ChangeNotifier {
  String plotText = "";

  List<Movie> _movies = [];

  List<Movie> get movies {
    return <Movie>[..._movies];
  }

  .....

  Future<void> fetchAndSetMovies() async {
    const url = 'http://192.168.1.142:8000/Desktop/textData.json';

    try {
      final response = await http.get(
        Uri.parse(url),
      );
      String source = Utf8Decoder().convert(response.bodyBytes);

      final extractedData =
          List<Map<String, dynamic>>.from(json.decode(source));
      final List<Movie> loadedMovies = [];

      extractedData.forEach(
        ((movieInfo) => {
              loadedMovies.add(Movie(
                id: movieInfo['id'],
                age: 12,
                countries: List<String>.from(movieInfo['country']),
                description: movieInfo['descriprion'],
                frames: movieInfo['frames'],
                genre: movieInfo['genre'],
                poster: movieInfo['poster'],
                premiereWorld: movieInfo['date'].toString(),
                ratingIMDb: movieInfo['ratingIMDb'],
                ratingKinopoisk: movieInfo['ratingKinopoisk'],
                title: movieInfo['title'][1],
                ifSeries: movieInfo['ifSeries'],
                dateTo: movieInfo['dateTo'].toString(),
                isFavourite: true,
                seasons: movieInfo['seasons'],
              )),
            }),
      );
      _movies = loadedMovies;
      notifyListeners();
    } on Exception catch (e) {
      print('error');
      print(e.toString());
    }
  }
}

Swipe_event.dart

part of 'swipe_block.dart';

abstract class SwipeEvent extends Equatable {
  const SwipeEvent();

  @override
  List<Object> get props => [];
}

class LoadMoviesEvent extends SwipeEvent {
  final List<Movie> movies ;

  LoadMoviesEvent({
    required this.movies,
  });

  @override
  List<Object> get props => [movies];
}

class SwipeLeftEvent extends SwipeEvent {
  final Movie movie;

  SwipeLeftEvent({
    required this.movie,
  });

  @override
  List<Object> get props => [movie];
}

class SwipeRightEvent extends SwipeEvent {
  final Movie movie;

  SwipeRightEvent({
    required this.movie,
  });

  @override
  List<Object> get props => [movie];
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

九公里浅绿 2025-01-26 14:54:25

您可能需要将代码调用provider.of(context)移动到其自己的小部件中。由于错误意味着您不能使用提供商在用于设置提供商范围的同一buildContext内检索依赖项。创建一个新的小部件还将生成新的buildContext。

如果您确实需要使用provider.of(context)在同一类中,则可以使用 builder 窗口小部件生成新的上下文。

You probably need to move the code calling Provider.of(context) into its own widget. As the error implies you can't use Provider to retrieve dependencies within the same BuildContext you used to set the Provider scope. Creating a new widget will also generate a new BuildContext.

If you really need to use Provider.of(context) in the same class you define MultiProvider you could use the Builder widget to generate a new context.

白色秋天 2025-01-26 14:54:25

因此,要解决此问题,您不应在main.dart中使用BlocProvider。您应该在将实现集团提供商的直接小部件中使用它。所以我在一个屏幕上使用它 - 建议,所以我像这样写了

class RecomendationsScreen extends StatelessWidget {
  static const routeName = '/recomendations';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: kBackgroundColor,
      body: BlocProvider(
        create: (_) => SwipeBloc()
          ..add(
            LoadMoviesEvent(
              movies: Provider.of<Movies>(context).movies,
            ),
          ),
        child: RecomendationsBody(),
      ),
    );
  }
}

So, to solve this problem you should NOT use BlocProvider in main.dart. You should use it in that direct widget where BLoC Provider will be implemented. So I use it in one screen - recomendations, so I write it there like this

class RecomendationsScreen extends StatelessWidget {
  static const routeName = '/recomendations';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: kBackgroundColor,
      body: BlocProvider(
        create: (_) => SwipeBloc()
          ..add(
            LoadMoviesEvent(
              movies: Provider.of<Movies>(context).movies,
            ),
          ),
        child: RecomendationsBody(),
      ),
    );
  }
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文