【问题标题】:Flutter: how to create a Singleton from an http requestFlutter:如何从 http 请求创建单例
【发布时间】:2018-08-29 12:53:06
【问题描述】:

我想声明一个用户对象,我将使用 http 请求进行实例化,并且我希望它是全局的。我该怎么做?有一个单身人士?但是我怎样才能让这个类也成为单例呢?还是有其他方法? 这就是我到目前为止所做的:

class User{
String username;
String password;
  int id;

User({this.username, this.id});

  factory User.fromJson(Map<String, dynamic> json){
    return User(
      username: json['name'],
      id: json['id']
    );
  }

}

然后:

var user = await login(username, password, context);

【问题讨论】:

  • 您真的不希望在您的应用程序中使用单例。我认为您真正想要的是一种访问在 Widget 树顶部附近共享的 User 对象的方法。你可以使用scoped_model 之类的东西。通过这种方式,您可以将 User 对象定义为模型,并提供执行登录的方法,将 ScopedModel&lt;User&gt; 包裹在您的根目录周围,并在您有登录按钮或用户名文本标签的地方使用 ScopedModelDescendant&lt;User&gt;
  • 可能是一个愚蠢的问题,但如果我使用 Navigator.of(context).pushNamedAndRemoveUntilscopedModelDescendant 会找到用户对象还是不会? t?
  • Navigator.of 将向上搜索小部件层次结构,直到找到最近的 NavigatorState。如果您只使用 WidgetsApp 或 MaterialApp 提供导航,那么它将找到的小部件。这意味着只要您使用ScopedModel&lt;User&gt; 包装您的应用程序,那么即使您更改路由,作用域模型后代也将能够找到它。
  • 非常感谢!

标签: http dart flutter


【解决方案1】:

在颤振中,你不应该做单例。相反,您应该将其存储到一个小部件中,该小部件将这些数据公开给它的所有后代。 通常InheritedWidget

原因是,有了这样的架构,所有后代都会自动知道对您的“单例”所做的任何更改。

一个典型的例子如下:

@immutable
class User {
  final String name;

  User({this.name});
}

class Authentificator extends StatefulWidget {
  static User currentUser(BuildContext context) {
    final _AuthentificatorScope scope = context.inheritFromWidgetOfExactType(_AuthentificatorScope);
    return scope.user;
  }

  final Widget child;

  Authentificator({this.child, Key key}): super(key: key);

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

class _AuthentificatorState extends State<Authentificator> {
  @override
  Widget build(BuildContext context) {
    return _AuthentificatorScope(
      child: widget.child,
    );
  }
}

class _AuthentificatorScope extends InheritedWidget {
  final User user;

  _AuthentificatorScope({this.user, Widget child, Key key}) : super(child: child, key: key);

  @override
  bool updateShouldNotify(_AuthentificatorScope oldWidget) {
    return user != oldWidget.user;
  }
}

你必须像这样实例化它:

new MaterialApp(
  title: 'Flutter Demo',
  builder: (context, child) {
    return Authentificator(
      child: child,
    );
  },
  home: Home(),
);

然后像这样在你的页面中使用:

@override
Widget build(BuildContext context) {
  User user = Authentificator.currentUser(context);
  ...
}

【讨论】:

  • 可能是一个愚蠢的问题,但如果我使用 Navigator.of(context).pushNamedAndRemoveUntil,它会不会一样工作?
  • 不确定你的意思
  • 例如,在 作用域模型 中,它遍历 Widget 树。我不知道 remove 是否会删除这些关系。可能不是,只是问
  • 没有导航器堆栈和小部件树不相关
  • 非常感谢!
猜你喜欢
  • 1970-01-01
  • 2019-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-02
相关资源
最近更新 更多