Flutter 颤振:StatefulWidget中的作用域模型访问

Flutter 颤振:StatefulWidget中的作用域模型访问,flutter,dart,scoped-model,Flutter,Dart,Scoped Model,我有作用域模型lib/scoped_models/main.dart: import 'package:scoped_model/scoped_model.dart'; class MainModel extends Model { int _count = 0; int get count { return _count; } void incrementCount() { _count += 1; notifyListeners(); }

我有作用域模型
lib/scoped_models/main.dart

import 'package:scoped_model/scoped_model.dart';

class MainModel extends Model {
  int _count = 0;

  int get count {
    return _count;
  }
  
  void incrementCount() {
    _count += 1;
    notifyListeners();
  }

  void setCount(int value) {
    _count = value;
    notifyListeners();
}
import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import 'package:scoped_m_test/scoped_models/main.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ScopedModel<MainModel>(
        model: MainModel(),
        child: MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        )
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final MainModel _model = MainModel();

  void initState() {
    super.initState();
    // _model.incrementCount(); // <-- doesn't work !!!
  }
  
  void _incrementCounter() {
    setState(() {
      // _model.incrementCount(); // <-- doesn't work !!!
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            ScopedModelDescendant<MainModel>(
              builder: (BuildContext context, Widget child, MainModel model) {
                return Text(
                  '${model.count}',
                  style: Theme.of(context).textTheme.headline4,
                );
              }
            )
          ],
        ),
      ),
      floatingActionButton: ScopedModelDescendant<MainModel>(
        builder: (BuildContext context, Widget child, MainModel model) {
          return FloatingActionButton(
            onPressed: () {
              model.incrementCount(); // <-- only this works !!!
              // _incrementCounter(); // <-- doesn't work !!!
            },
            tooltip: 'Increment',
            child: Icon(Icons.add),
          );
        }
      )
    );
  }
}

import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import 'package:scoped_m_test/scoped_models/main.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ScopedModel<MainModel>(
        model: mainModel, // <-- instance of model from 'lib/<app_name>/scoped_models/main.dart'
        child: MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        )
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  void initState() {
    super.initState();
  }
  
  void _incrementCounter() {
    setState(() {
      mainModel.incrementCount(); // <-- now it works !!!
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            ScopedModelDescendant<MainModel>(
              builder: (BuildContext context, Widget child, MainModel model) {
                return Text(
                  '${model.count}',
                  style: Theme.of(context).textTheme.headline4,
                );
              }
            )
          ],
        ),
      ),
      floatingActionButton: ScopedModelDescendant<MainModel>(
        builder: (BuildContext context, Widget child, MainModel model) {
          return FloatingActionButton(
            onPressed: () {
              // model.incrementCount(); // <-- works !!!
              _incrementCounter(); // <-- now it's working too !!!
            },
            tooltip: 'Increment',
            child: Icon(Icons.add),
          );
        }
      )
    );
  }
}
非常简单的应用程序
lib/main.dart

import 'package:scoped_model/scoped_model.dart';

class MainModel extends Model {
  int _count = 0;

  int get count {
    return _count;
  }
  
  void incrementCount() {
    _count += 1;
    notifyListeners();
  }

  void setCount(int value) {
    _count = value;
    notifyListeners();
}
import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import 'package:scoped_m_test/scoped_models/main.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ScopedModel<MainModel>(
        model: MainModel(),
        child: MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        )
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final MainModel _model = MainModel();

  void initState() {
    super.initState();
    // _model.incrementCount(); // <-- doesn't work !!!
  }
  
  void _incrementCounter() {
    setState(() {
      // _model.incrementCount(); // <-- doesn't work !!!
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            ScopedModelDescendant<MainModel>(
              builder: (BuildContext context, Widget child, MainModel model) {
                return Text(
                  '${model.count}',
                  style: Theme.of(context).textTheme.headline4,
                );
              }
            )
          ],
        ),
      ),
      floatingActionButton: ScopedModelDescendant<MainModel>(
        builder: (BuildContext context, Widget child, MainModel model) {
          return FloatingActionButton(
            onPressed: () {
              model.incrementCount(); // <-- only this works !!!
              // _incrementCounter(); // <-- doesn't work !!!
            },
            tooltip: 'Increment',
            child: Icon(Icons.add),
          );
        }
      )
    );
  }
}

import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import 'package:scoped_m_test/scoped_models/main.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ScopedModel<MainModel>(
        model: mainModel, // <-- instance of model from 'lib/<app_name>/scoped_models/main.dart'
        child: MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        )
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  void initState() {
    super.initState();
  }
  
  void _incrementCounter() {
    setState(() {
      mainModel.incrementCount(); // <-- now it works !!!
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            ScopedModelDescendant<MainModel>(
              builder: (BuildContext context, Widget child, MainModel model) {
                return Text(
                  '${model.count}',
                  style: Theme.of(context).textTheme.headline4,
                );
              }
            )
          ],
        ),
      ),
      floatingActionButton: ScopedModelDescendant<MainModel>(
        builder: (BuildContext context, Widget child, MainModel model) {
          return FloatingActionButton(
            onPressed: () {
              // model.incrementCount(); // <-- works !!!
              _incrementCounter(); // <-- now it's working too !!!
            },
            tooltip: 'Increment',
            child: Icon(Icons.add),
          );
        }
      )
    );
  }
}
导入“包装:颤振/材料.省道”;
导入“package:scoped_model/scoped_model.dart”;
导入“package:scoped_m_test/scoped_models/main.dart”;
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回范围模型(
模型:MainModel(),
孩子:MaterialApp(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
视觉密度:视觉密度。自适应平台密度,
),
主页:MyHomePage(标题:“颤振演示主页”),
)
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
最终主模型_model=MainModel();
void initState(){
super.initState();

//_model.incrementCount();//在查看了我的代码一段时间后,我意识到修复代码是多么简单

因此,显然,对于项目的所有小部件和文件,应该只有一个
MainModel()
实例,为了方便起见,应该将其放置在作用域模型文件
lib/scoped_models/main.dart
中,如下所示:

import 'package:scoped_model/scoped_model.dart';

final MainModel mainModel = MainModel(); // <-- create instance once for all files which require scoped model import

class MainModel extends Model {
  int _count = 0;

  int get count {
    return _count;
  }
  
  void incrementCount() {
    _count += 1;
    notifyListeners();
  }

  void setCount(int value) {
    _count = value;
    notifyListeners();
}
尽管这一事实似乎是合理的,但由于缺乏示例,它也可能第一次被淹没。我希望这对某些人有所帮助。

使用作用域模型作为提供者
  • 在使用它的小部件(MyHomePage)之前添加
    ScopedModel
  • 使用
    ScopedModel.of(context)
    控制模型
  • 使用
    scopedModeleScendant
    收听模型
使用此选项的优点是:

  • 您可以在子体中访问相同的模型并轻松共享数据
  • 尽可能小地重建小部件(仅重建ScopedModelSecondant部分)
代码:

MyHomePage

  • MainModel
    甚至不需要扩展模型或使用notifyListeners,因为小部件使用
    setState
    来重建
代码:

类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
void initState(){
super.initState();
}
void _incrementCounter(){
设置状态(){
mainModel.incrementCount();
});
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(widget.title),
),
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
正文(
“您已经按了这么多次按钮:”,
),
正文(
“${mainModel.count}”,
风格:Theme.of(context).textTheme.headline4,
),
],
),
),
浮动操作按钮:浮动操作按钮(
已按下:(){
_递增计数器();
},
工具提示:“增量”,
子:图标(Icons.add),
),
);
}
}

你把你的
mainModel
作为一个全局单体,这有点奇怪,为什么你还需要
ScopedModel
呢?你可以简单地使用
class mainModel extends change notifier
并在任何地方读/写它。谢谢你的评论,但我不知道如何正确地实现你的方法。我试着在另一方面解释它回答。如果你有任何进一步的问题,请告诉我。