Dart 中的全局变量
Posted
技术标签:
【中文标题】Dart 中的全局变量【英文标题】:Global Variables in Dart 【发布时间】:2015-05-24 19:26:11 【问题描述】:我尝试创建一个 Dart 单页应用程序。
我创建了第一个自定义元素 (custom-application
),其中包含整个应用程序。
它有一个用于渲染视图的容器。还有一个包含用户信息并在用户登录时更新的侧导航。
我想在视图之间共享信息。
如何在custom-application
中定义一个全局变量并能够与其他视图共享?
例如,当您启动应用程序时,您没有经过身份验证。当您调用 /login (login-view
) 时,您将获得一个登录表单。我希望,当您登录应用程序时,custom-application
元素存储嵌套视图 login-view
加载的用户信息并更新侧导航。
有可能吗?
【问题讨论】:
【参考方案1】:只需创建一个库文件并为您需要的全局变量创建字段。在您需要访问这些字段的任何地方导入此库。
app.dart
import 'globals.dart' as globals;
main()
globals.isLoggedIn = true;
component1.dart
import 'globals.dart' as globals;
class MyComponent
view()
if(globals.isLoggedIn)
doSomething();
else
doSomethingElse();
globals.dart
library my_prj.globals;
bool isLoggedIn = false;
你也可以
在全局库中创建一个单例(有关详细信息,请参阅How do you build a Singleton in Dart?)。 使用 observable 获取更改通知(请参阅Implement an Observer pattern in Dart、How can i trigger a kind of onChange event in a class 了解更多详情)【讨论】:
我终于成功地使用可观察模式将全局变量作为可观察的。它工作得很好。再次感谢您。 糟糕,我很抱歉 - 我的评论有点断章取义。不 - 从我尝试过的有限测试来看,当从计算执行的回调中访问全局变量时,这似乎不起作用。当我有时间时,我会提出一个适当的问题。 @GünterZöchbauerlibrary my_prj.globals
在globals.dart
文件中做了什么?
该库声明在早期的 Dart 版本中是强制性的,但最终成为可选的,我认为没有人再使用它了。每个不是零件文件的 Dart 文件都需要一个唯一的库声明。如果未明确添加,则从文件名+路径派生。
@GünterZöchbauer 实际上,图书馆声明不是必需的。我刚刚尝试将其从代码中删除,但“编辑队列已满”。【参考方案2】:
++++ 2019 年 7 月更新 ++++
我写了一个集成了 Flutter Global Config 的 Package。
EZ Flutter 是小部件、包和许多有用的东西的集合,混合在一个小框架中。目的是从头开始提供标准功能。 EZ Flutter 支持管理可在应用内部访问的不同配置文件。
Github:https://github.com/Ephenodrom/EZ-Flutter
dependencies:
ez_flutter: ^0.2.0
查看文档如何使用不同的配置。
https://github.com/Ephenodrom/EZ-Flutter/blob/master/documentation/APPLICATION_SETTINGS.md
++++ 旧答案 ++++
我对全局变量也有同样的问题。因此,我还需要为每个应用程序版本(dev / prod)进行不同的配置,并且我不想将配置写入 main_dev.dart 或 main_prod.dart 文件中。
我编写了一个简单的 Flutter 包,用于处理分离的配置文件并在应用启动时加载它们。然后,您的应用中的每一行代码都可以使用该配置。
https://github.com/Ephenodrom/Flutter-Global-Config
如何使用它:
在assets/cfg/$file.json下创建一个json文件
将资产/cfg 添加到您的 pubspec.yaml
在应用启动时加载不同的配置文件:
import 'package:flutter/material.dart';
import 'package:global_configuration/global_configuration.dart';
void main() async
await GlobalConfiguration().loadFromAsset("app_settings");
await GlobalConfiguration().loadFromAsset("env_dev_settings");
runApp(MyApp());
class MyApp extends StatelessWidget
...
在您的应用中使用配置:
import 'package:flutter/material.dart';
import 'package:global_configuration/global_configuration.dart';
class CustomWidget extends StatelessWidget
CustomWiget()
// Access the config in the constructor
print(GlobalConfiguration().getString("key1"); // prints value1
@override
Widget build(BuildContext context)
// Access the config in the build method
return new Text(GlobalConfiguration().getString("key2"));
【讨论】:
【参考方案3】:你可以创建一个类
myColors.dart
class AppColors
static var primary = Colors.blue;
并导入您的课程
import 'package:myapp/.../myColors.dart';
并通过AppColors.primary
访问
【讨论】:
这个真的很简单! 静态变量不是在 dart 中访问和更新变量的首选方式。静态变量可能会跨文件丢失其数据(请参阅***.com/questions/45772318)。【参考方案4】:基于库的思想,这里有一种方法可以将任何类型的“键控”全局变量添加到从其他小部件调用的映射中。这样您就不必事先声明这些变量。如果变量不存在,则由 appDataSet 将其添加到地图中。 因此,在像复选框这样的小部件中,您可以在 setState() 函数中添加例如:appDataSet('aCheckBox',value);如果地图中不存在aCheckBox,则添加它并加载值(在本例中为布尔值)。
library my_prj.globals;
Map appData = Map<String,dynamic>();
void appDataSet(String key, dynamic value)
if (!appData.containsKey(key))
appData.putIfAbsent(key, () => value);
else
appData.update(key, (dynamic) => value);
print(appData);
dynamic appDataGet(String key)
if (appData.containsKey(key))
return (appData.putIfAbsent(key, () => ));
else
return (null);
【讨论】:
【参考方案5】:您只需要创建一个像“constants.dart”这样的文件
import '...materials.dart';
const Color baseColor = Color(0XFF353535);
并像这样使用
import '...constants.dart';
.......
......
....
Container(
color: baseColor,
.....
),
【讨论】:
【参考方案6】:我创建了一个名为 my-globals.dart 的 dart 文件,我可以在其中定义我的全局变量。
像这样:
library globals;
int globalInt = 0;
bool globalBoolean = true;
String globalString = "";
double globalDouble= 10.0;
这就是整个 dart 文件。
然后,在同一个目录或文件夹中,我可以创建其他类,我可以通过将 my-globals.dart 作为全局变量导入来访问我的全局变量。让我们创建一个扩展 StatefulWidget 的类。在那里,我们将通过按下平面按钮来更改名为 globalInt 的全局变量的值。
import 'package:flutter/material.dart';
import 'my-globals.dart' as globals;
class OtherClass extends StatefulWidget
OtherClass(Key key) : super(key: key);
@override
_OtherClassState createState() => _OtherClassState();
class _OtherClassState extends State<OtherClass>
@override
Widget build(BuildContext context)
return Container(
child: FlatButton(
color: Colors.blue,
textColor: Colors.white,
onPressed: ()
setState(() globals.globalInt++;);
print(globals.globalInt);
,
),
);
你看。我只是通过编写全局变量来访问我想要的变量。然后是库中包含的变量的名称。
希望这个例子有助于更好地理解如何使用全局库。
【讨论】:
【参考方案7】:全局变量通常不受欢迎。 Flutter 的推荐解决方案是提供程序库。它只是一个小部件,您将其插入到小部件树的某个较高位置并赋予它一些值(对象、类)来保存。然后您可以更深入地访问其他小部件中的值。
与全局变量相反,您可以修改提供程序存储的值,并且内部深处的小部件将重新渲染。
pub.dev/provider
存储价值
Widget build(BuildContext context)
String someValue = '5';
return Provider(
create: (_) => someValue),
child: SafeArea(...)
);
获取值:
@override
void initState()
super.initState();
WidgetsBinding.instance?.addPostFrameCallback((timeStamp)
setState(()
value5 = context.read<String>();
);
);
【讨论】:
以上是关于Dart 中的全局变量的主要内容,如果未能解决你的问题,请参考以下文章