代码之家  ›  专栏  ›  技术社区  ›  oliverbytes

如何在颤振中从第3页调用第1页的函数?

  •  0
  • oliverbytes  · 技术社区  · 6 年前

    我基本上需要从另一个页面调用一个函数。这是我的导航结构:第一个屏幕>第二个屏幕>第三个屏幕。

    我已经读了很多关于我的问题的话题,但是我还不能得到完美的答案。我试过用 ScopedModel InheritedWidgets 但它需要树上的一个小部件来传递数据。

    我正在使用导航器的命名路由 pushNamed() 函数来推送这些页面。

    假设我的第一个屏幕有一个列表视图和一个刷新它的函数: void refresh() . 我怎么打电话给 refresh() 直接从第三个屏幕开始工作?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Epizon    6 年前

    你可以用多种方法 一些常见的方法是

    1. 通过构造函数向下传递函数并调用它
    2. 使用RXDART
    3. 使用范围模型或任何状态管理库
        2
  •  0
  •   oliverbytes    6 年前

    我已经找到了完美的解决方案。我必须使用scoped_model包,创建一个用作ListView数据源的模型,如果我尝试更改模型的值,它应该在应用程序的任何位置自动更新。一种不使用ScopedModelDescendant小部件的静态方法是调用 ScopedModel.of<MyModel>(context, rebuildOnChange: true).refresh();

    DART文件

    class DataModel extends Model {
      bool _loading = false;
    
      String _data = "";
    
      bool get loading => _loading;
      String get data => _data;
    
      void refresh() {
        this._loading = true;
        print("loading...");
        notifyListeners();
    
        String url = "https://reqres.in/api/users/2?delay=1";
        http.get(url).then((response) {
          _loading = false;
          print("refreshed data: ${response.body}");
          this._data = response.body;
          notifyListeners();
        });
      }
    
      static DataModel of(BuildContext context) =>
          ScopedModel.of<DataModel>(context);
    }
    

    MI. DART文件

    void main() => runApp(MyApp(model: DataModel()));
    
    class MyApp extends StatelessWidget {
      final DataModel model;
      const MyApp({Key key, @required this.model}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return ScopedModel<DataModel>(
          model: model,
          child: MaterialApp(
            title: 'ScopedModel Demo',
            routes: {
              '/': (_) => MyHomePage(title: 'Home Page'),
              '/settings': (_) => SettingsPage(),
            },
          ),
        );
      }
    }
    

    home.dart文件

    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
    
      @override
        void initState() {
          // I can fetch new data here statically without the use of the ScopedModelDescendant in the widget tree.
          DataModel.of(context).refresh();
          super.initState();
        }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: ScopedModelDescendant<DataModel>(
            builder: (context, child, model) {
              return Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text(model.loading ? "LOADING..." : ""),
                    Text("data: ${model.data}"),
                    // Statically reading the value from the model
                    RaisedButton(child: Text("Read value statically"), onPressed: () {
                      String value = DataModel.of(context).data;
                      print("$value");
                    },),
                    RaisedButton(child: Text("Settings"), onPressed: () {
                      Navigator.pushNamed(context, "/settings");
                    },)
                  ],
                ),
              );
            },
          ),
          floatingActionButton: ScopedModelDescendant<DataModel>(
            builder: (context, child, model) {
              return FloatingActionButton(
                child: Icon(Icons.refresh),
                onPressed: () {
                  // here is the ScopedModelDescendant version of refreshing data
                  model.refresh();
                },
              );
            },
          ),
        );
      }
    }