flutter - Dart,在代理模式中以 DRY 或合成方式覆盖许多 getter 和 setter
问题描述
让我们参加这个飞镖课程:
class Subject {
String a;
String b;
String c;
}
现在我想通过代理使用它来管理延迟加载和同步。
当我从网络加载真实数据时,我还希望有默认值用作占位符。为了保持大腿整洁和独立,我添加了另一个类:
class Fallback implements Subject {
@override String a = 'a';
@override String b = 'b';
@override String c = 'c';
}
现在我有了写下“带有后备的代理”类所需的所有砖块:
class Proxy implements Subject {
Subject model;
Subject fallback = Fallback();
Future<void> slowlyPopulateModel() async => if (model == null) ... // do some async stuff that valorize model
@override
String get a {
slowlyPopulateModel();
return model?.a ?? fallback.a;
}
@override
set a(String _a) {
model?.a = a;
notifyListener();
}
// same getters and setters for b and c
}
如果需要,通过覆盖get a
我可以调用慢速 I/O 方法并返回我的Fallback
类的占位符值。一旦设置了新值,我的重写set a(String _a)
将调用notifyListener()
它将更新我的界面。
它工作正常,但我已经为我班级的每个字段手动覆盖了 getter 和 setter(它们很多)。
Dart 有什么技巧可以以更干的方式做到这一点吗?
例如,某种方式可以在每个 getter 或 setter 之前或之后注入要执行的代码?
解决方案
我建议看看Streams
这个。
此代码示例将返回一个初始值,获取一个新值并通过流通知侦听器。
import 'dart:async';
class Subject {
// Current value, initially at "a"
String _a = "a";
StreamController<String> _aController = StreamController<String>();
String get a {
_updateA();
return _a;
}
Stream<String> get aStream => _aController.stream;
void _updateA() async {
String newValue = await _fetchA();
_a = newValue; // update the current value
_aController.add(newValue); // push the new value onto the stream for listeners
}
// return a String after two seconds
Future<String> _fetchA() async {
return Future.delayed(
Duration(seconds: 2),
() => "New value for _a",
);
}
// This closes the stream
void dispose() {
_aController.close();
}
}
main(args) {
final subject = Subject();
// listen to changes
subject.aStream.listen((value) {
print("new value of a: $value");
});
// get current value
final currentValue = subject.a;
print("current value of a: $currentValue");
}
这个例子的输出
a的当前值:a
(两秒后) a 的新值:_a 的新值
在 Flutter 中使用它StreamBuilder
StreamBuilder<String>(
stream: subject.aStream,
initialData: subject.a,
builder: (context, snapshot) {
final valueOfA = snapshot.data;
return Text("value is $valueOfA");
}
)
一些样板代码可以被RxDart中的BehaviorSubject替换。但这需要将另一个依赖项导入到项目中。
推荐阅读
- php - 如何在php中将数组合并为单个数组?
- python - ValueError: x 和 y 必须具有相同的第一维,但具有形状 (50,) 和 (1, 50)/ 多处理
- monaco-editor - 覆盖摩纳哥编辑器悬停小部件样式以隐藏“偷看问题”
- go - go-swagger:没有可用于解组的规范
- python - 在 Python 中的 mysql 连接中出现错误
- javascript - 删除显示的项目列表的问题
- python - 格式不显示
- c# - 如何仅过滤和搜索选定字段并排除 ASP.NET MVC 中的空文本框
- mysql - 使用 Intellij 通过 kubernetes pod 连接到 MySQL 服务器
- django - 获取子查询的计数