Ошибка флаттера: не удалось найти правильную ScopedModel

Я пытаюсь создать модель области действия в своем проекте флаттера, и я не могу понять, почему я получаю сообщение об ошибке. Что не так в этой реализации модели? У меня домашняя страница с нижним навигатором. На вкладке профиля я получаю список подписчиков, которые мне нужны, в виджете глубоко в дереве, поэтому я пытаюсь использовать scopedmodel.

Код модели

class RelationshipsModel extends Model {
        List<Relationship> relations;
        RelationshipsModel(this.relations);
        void add(String name) {
            relations.add(new Relationship("", "", name, name));
            notifyListeners();
      }
    }

Страница профиля, которая создает scopedmodel, находится ниже. Здесь я получаю список подписчиков из Firebase в состоянии и использую его для создания модели для модели области действия.

 class ProfileWidget extends StatefulWidget {
      @override
      _ProfileWidgetState createState() => _ProfileWidgetState();
    }

class _ProfileWidgetState extends State<ProfileWidget> {
@override
  initState() {
    super.initState();
    getCurrentUserDetails();
  }
getCurrentUserDetails() async {
_name = await CacheService.getCurrentUser();
var following = await service.getFollowingList(_name);
setState(() {
      this._following = following;
    });
  }

 @override
  Widget build(BuildContext context) {
    if (this._name == null) {
      return new Container(
        child: const CupertinoActivityIndicator(),
      );
    }

return  ScopedModel<RelationshipsModel>(
        model: RelationshipsModel(this._following),
        child: Scaffold(
       //more stuff

         background: new Stack(children: <Widget>[
                  new CarouselWidget(),
                  new Align(
                    alignment: FractionalOffset.topCenter,
                    heightFactor: 6.0,
                    child: new Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        //Here I am creating the a widget that shows the list of followers and following
                        new FollowerInfoWidget(followers: this._followers,
                            following: this._following),
                      ],
                    ),
                  ),
                ])),


     )
   );
  }
}

Ниже приведен FollowerInfoWidget, который вызывает ProfileWidget или UserWidget на основе выбранного пользователя из списка.

 class _FollowerState extends State<FollowerWidget> {

  Widget buildListTile(BuildContext context, Relationship item) {
    return new MergeSemantics(
      child: new ListTile(

        title: new Text(item.followerId),
        onTap: () async {
          if (item.followerId == await CacheService.getCurrentUser()) {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => ProfileWidget()),
            );
          }
          else {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) =>
                  UserWidget(name: item.followerId)),
            );
          }
        },
        trailing: new Icon(Icons.info, color: Theme.of(context).disabledColor),
      ),
    );
  }

Кнопка FollowUnFollowWidget является частью UserWidget.

    class UserWidget extends StatefulWidget {
  UserWidget(
      {Key key})
      : super(key: key);
  @override
  _UserWidgetState createState() => _UserWidgetState();
}

class _UserWidgetState extends State<UserWidget> {
@override
  Widget build(BuildContext context) {
return Scaffold(
      body: DefaultTabController(
//more stuff
 new FollowerInfoWidget(
                              followers: this._followers,
                              following: this._following,
                            ),
                            new FollowUnFollowWidget ()

И виджет с ScopedModelDescendant ниже

class FollowUnFollowWidget extends StatelessWidget {  
  @override
  Widget build(BuildContext context) {
    return ScopedModelDescendant<RelationshipsModel>(
        builder: (context, child, model) =>
            FloatingActionButton(
            onPressed: () {}
           //more stuff
       )
    );
  }
}

person Shruthi    schedule 21.08.2018    source источник
comment
Где в дереве виджетов находится FollowUnFollowWidget? Он находится в разделе //дополнительных материалов вашего ProfileWidget?   -  person aqwert    schedule 22.08.2018
comment
Нет, он вызывается из другого виджета, который, в свою очередь, вызывается из ProfileWidget. ProfileWidget -> UserWidget -> FollowUnfollowWidget   -  person Shruthi    schedule 22.08.2018
comment
Можете ли вы показать немного больше на своем примере виджетов, которые вы упомянули.   -  person aqwert    schedule 22.08.2018
comment
Таким образом, ProfileWidget представляет профиль пользователя, который показывает количество пользователей, за которыми следят, и количество подписчиков. Эти 2 числа являются интерактивным текстом, который показывает всех пользователей в этом списке. При выборе пользователя из этого списка вызывается UserWidget, который также имеет кнопку, чтобы подписаться/отписаться от этого пользователя. Я отредактировал свой первоначальный вопрос, чтобы добавить больше кода   -  person Shruthi    schedule 22.08.2018
comment
Добавлен ответ, который может быть вашей проблемой   -  person aqwert    schedule 22.08.2018


Ответы (3)


Этот код здесь подтолкнет представление, которое является либо ProfileWidget, либо UserWidget

onTap: () async {
      if (item.followerId == await CacheService.getCurrentUser()) {
        Navigator.push(
          context,
          MaterialPageRoute(builder: (context) => ProfileWidget()),
        );
      }
      else {
        Navigator.push(
          context,
          MaterialPageRoute(builder: (context) =>
              UserWidget(name: item.followerId)),
        );
      }
    },

Поскольку UserWidget имеет FollowUnFollowWidget, использование ScopedModelDescendant не сработает, так как над ним нет ScopedModel. Этот ScopedModel определяется только с помощью ProfileWidget

Похоже, вам нужно добавить ScopedModel либо в начало метода сборки UserWidget, либо как часть buildListTile.

person aqwert    schedule 21.08.2018

Если у кого-то есть такая же ошибка, ошибка также может быть контекстом. В некоторых случаях он не находит модель Scoped, потому что контекст не соответствует тому, где вы начинаете свою основную ScopedModel.

person AlexPad    schedule 03.07.2019

Вам нужно добавить модель области в main.dart следующим образом:

@override
  Widget build(BuildContext context){
    return ScopedModel<UserModel>(
        model: UserModel(),
        child: MaterialApp(
            title: "YourApp",
            debugShowCheckedModeBanner: false,
            home: Scaffold(
              body: HomeScreen(),
            )
        )
    );
  }
person murilopbs    schedule 04.01.2021