gpt4 book ai didi

dart - 观察一个包含可观察列表的对象?

转载 作者:行者123 更新时间:2023-12-01 15:39:20 25 4
gpt4 key购买 nike

我正在使用 observe package .

考虑这个例子:

class Product extends Object with ChangeNotifier {

double _price = 0.0;

@reflectable double get price => _price;
@reflectable void set price(double value) {
if (value == null) throw new ArgumentError();
_price = notifyPropertyChange(#price, price, value);
}
}

class Order extends Object with ChangeNotifier {

final ObservableList<Product> products = new ObservableList<Product>();

double get total {
double sum = 0.0;
for (var item in products) {
sum += item.price;
}
return sum;
}
}

// Synchronizes the view total with the order total.
// Or rather, I'd like it to do that.
var order = new Order();
order.changes.listen((records) {
view.total = order.total;
});

我将如何重写这个示例以使其工作?

我希望在对象状态发生任何变化时得到通知,即使它们发生在列表或列表中的项目上也是如此。

我是否必须管理对所有项目和列表本身的更改订阅?在 Order 类的内部还是外部?我将通过哪个属性通知更改?无论哪种方式看起来都很困惑。

最佳答案

ObservableList 中的元素不会将通知传播到包含它们的列表。他们不能,因为他们没有引用列表。此外,该列表不会将通知转发给它所引用的类。

不是很令人满意,但这是我能想到的最好的。

import 'dart:async' as async;
import 'package:observe/observe.dart';

class Product extends Object with ChangeNotifier {

double _price = 0.0;

@reflectable double get price => _price;
@reflectable void set price(double value) {
if (value == null) throw new ArgumentError();
_price = notifyPropertyChange(#price, price, value);
}

@override
String toString() => 'Product - price: $price';
}

class Order extends Object with ChangeNotifier {

final ObservableList<Product> products = new ObservableList<Product>();

// keep listeners to be able to cancel them
final List<async.StreamSubscription> subscriptions = [];

Order() {
products.changes.listen((cr) {
// only react to length changes (isEmpty, isNotempty changes are redundant)
var lengthChanges = cr.where((c) => c.name == #length);
if(lengthChanges.isNotEmpty) {
lengthChanges.forEach((lc) =>
notifyChange(lc));
// we can't know if only additions/removals were done therefore we
// cancel all existing listeners and set up new ones for all items
// after each length change
_updateProductsListeners();
}
});
// initial setup
_updateProductsListeners();
}

// cancel all product change listeners and create new ones
void _updateProductsListeners() {
print('updateListeners');
subscriptions.forEach((s) => s.cancel());
subscriptions.clear();
products.forEach((p)
=> subscriptions.add(p.changes.listen((crs) =>
crs.forEach((cr) =>
notifyPropertyChange(cr.name, cr.oldValue, cr.newValue)))));
}

double get total {
double sum = 0.0;
for (var item in products) {
sum += item.price;
}
return sum;
}
}

void main() {
// Synchronizes the view total with the order total.
// Or rather, I'd like it to do that.
var order = new Order();
order.changes.listen((records) {
//view.total = order.total;
records.forEach(print);
});

// a PathObserver example but it doesn't seem to be more convenient
var op = new PathObserver(order, 'products[3].price')..open((c) =>
print(c));

var prods = [new Product()..price = 1.0, new Product()..price = 2.0, new Product()..price = 3.0, new Product()..price= 4.0];
var prods2 = [new Product()..price = 5.0, new Product()..price = 6.0];

order.products.addAll(prods);

// use Future to allow change notification propagate between changes
new async.Future(() =>
order.products..addAll(prods2)..removeWhere((p) => p.price < 3.0))
.then((_) => new async.Future(() => order.products[3].price = 7.0));

new async.Future.delayed(new Duration(seconds: 1), () => print('done'));
}

我建议为此使用事件总线之类的东西,其中想要/应该通知某事的对象只是发送和事件以及对某事感兴趣的对象在不知道其他对象存在的情况下监听它。

例如https://pub.dartlang.org/packages/event_bus

关于dart - 观察一个包含可观察列表的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26089579/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com