首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ChangeNotifier + Provider的SearchDelegate

使用ChangeNotifier + Provider的SearchDelegate
EN

Stack Overflow用户
提问于 2019-08-23 08:52:45
回答 2查看 2K关注 0票数 0

如何在SearchDelegate中正确使用ChangeNotifier

我有一个类似这样的东西:

代码语言:javascript
复制
class SearchNotifier with ChangeNotifier {
  List<String> results;


  Future<void> search(String query) async {
    results = await API.search(query);
    notifyListeners();
  }
}

在我的SearchDelegate

代码语言:javascript
复制
Widget buildSuggestions(BuildContext context) {
  final searchNotifier = Provider.of<SearchNotifier>(context);
  searchNotifier.search(query);
  ...
}

当结果更新时,SearchNotifier更新其侦听器,重新构建SearchDelegate,调用buildSuggestions,然后再次调用search,进入循环。

有没有一种方法可以在searchNotifier.search(query)方法之外进行构建?也许我可以在SearchDelegate _queryTextController中添加一个监听器

我使用provider来注入我的SearchNotifier,所以无论在哪里调用search,我们都需要访问上下文。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-26 22:58:21

我通过直接从search方法返回搜索结果,然后使用FutureBuilder解决了这个问题。

代码语言:javascript
复制
class SearchNotifier with ChangeNotifier {
  Future<List<String>> search(String query) async {
    return await API.search(query);
  }
}

Widget buildSuggestions(BuildContext context) {
  final searchNotifier = Provider.of<SearchNotifier>(context);
  results = searchNotifier.search(query);
  // FutureBuilder on results
  ...
}

SearchNotifier不再需要成为ChangeNotifier,因为问题的根源是notifyListeners

票数 1
EN

Stack Overflow用户

发布于 2019-08-24 16:07:19

我做的不同,但我也在我的应用程序中使用提供者。因此,我的自定义搜索委托如下所示:

代码语言:javascript
复制
 class ExerciseSearchDelegate extends SearchDelegate {
  @override
  List<Widget> buildActions(BuildContext context) {
    return [
      IconButton(
        icon: Icon(Icons.clear),
        onPressed: () {
          query = '';
        },
      ),
    ];
  }

  @override
  Widget buildLeading(BuildContext context) {
    return IconButton(
      icon: Icon(Icons.arrow_back),
      onPressed: () {
        close(context, null);
      },
    );
  }

  @override
  Widget buildResults(BuildContext context) {
    // ExeciseList is a widget which accepts a query as optional parameter
    return ExerciseList(
      query: query,
    );
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    return Column();
  }

  @override
  ThemeData appBarTheme(BuildContext context) {
    assert(context != null);
    final ThemeData theme = Theme.of(context);
    assert(theme != null);
    return theme;
  }
}

我的ExerciseList是这样的:

代码语言:javascript
复制
class ExerciseList extends StatelessWidget {
  final String query;
  const ExerciseList({this.query, Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final _model = Provider.of<GlobalModel>(context);

    List<ExerciseModel> _results = query != null
        ? _model.exercises
            .where((ex) => ex.name.toLowerCase().contains(query.toLowerCase()))
            .toList()
        : _model.exercises;

    return ListView.builder(
      itemCount: _results.length,
      itemBuilder: (context, position) {
        var exercise = _results[position];
        return MultiProvider(
          providers: [
            ChangeNotifierProvider.value(notifier: exercise),
          ],
          child: ExerciseListItem(),
        );
      },
    );
  }
}

希望这能有所帮助。如果有什么不清楚的地方,请告诉我。谢谢!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57618579

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档