来自 EObjects 内容的嵌套可观察列表
Nested observable list from EObjects contents
我有一个具有以下结构的模型(在 Xcore 中指定):
class Network {
contains Master[] masters
}
class Master {
contains Slave[] slaves
}
class Slave {}
我想使用 EMF 数据绑定创建网络中所有主控对象中所有从属对象的可观察列表。
如何做到这一点?
或者:我可以创建一个可观察的奴隶列表的可观察列表吗?即 IObservableList<IObservableList<Slave>>
.
类型的结构
例如,以下内容不起作用:
Network network = ...
IObservableList allSlaves = EMFProperties
.list(Literals.NETWORK__MASTERS)
.values(Literals.MASTER__SLAVES)
.observe(network);
生成的列表似乎是 IObservableList<EList<Slave>>
类型,而不是所需的类型。问题是生成的 IObservableList
包含 class EObjectContainmentEList
的元素,这不是 IObservableList
.
事实证明,有一种方法可以创建嵌套的可观察列表,不仅适用于 EMF 列表功能,而且适用于所有类型的可观察列表。
诀窍是对 returns 可观察列表的工厂使用 MasterDetailObservables.detailValues
方法。
Network network = TryingFactory.eINSTANCE.createNetwork();
network.getMasters().add(TryingFactory.eINSTANCE.createMaster());
network.getMasters().add(TryingFactory.eINSTANCE.createMaster());
network.getMasters().get(0).getSlaves().add(TryingFactory.eINSTANCE.createSlave());
network.getMasters().get(1).getSlaves().add(TryingFactory.eINSTANCE.createSlave());
network.getMasters().get(1).getSlaves().add(TryingFactory.eINSTANCE.createSlave());
IObservableList<Master> masterList = EMFProperties.list(Literals.NETWORK__MASTERS).observe(network);
IObservableList<IObservableList<Slave>> nestedLists = MasterDetailObservables.detailValues(masterList,
master -> Observables.constantObservableValue(masterList.getRealm(),
EMFProperties.list(Literals.MASTER__SLAVES).observe(master),
IObservableList.class),
IObservableList.class);
// Dispose nested lists when they are removed from the top-level list
nestedLists.addListChangeListener(event -> event.diff.accept(new ListDiffVisitor<IObservableList<?>>() {
@Override
public void handleRemove(int index, IObservableList<?> element) {
element.dispose();
}
@Override public void handleAdd(int index, IObservableList<?> element) {}
@Override public void handleMove(int oldIndex, int newIndex, IObservableList<?> element) {}
}));
nestedLists.forEach(System.out::println);
// Prints:
// [trying.impl.SlaveImpl@7692d9cc]
// [trying.impl.SlaveImpl@75f32542, trying.impl.SlaveImpl@7f1302d6]
我有一个具有以下结构的模型(在 Xcore 中指定):
class Network {
contains Master[] masters
}
class Master {
contains Slave[] slaves
}
class Slave {}
我想使用 EMF 数据绑定创建网络中所有主控对象中所有从属对象的可观察列表。
如何做到这一点?
或者:我可以创建一个可观察的奴隶列表的可观察列表吗?即 IObservableList<IObservableList<Slave>>
.
例如,以下内容不起作用:
Network network = ...
IObservableList allSlaves = EMFProperties
.list(Literals.NETWORK__MASTERS)
.values(Literals.MASTER__SLAVES)
.observe(network);
生成的列表似乎是 IObservableList<EList<Slave>>
类型,而不是所需的类型。问题是生成的 IObservableList
包含 class EObjectContainmentEList
的元素,这不是 IObservableList
.
事实证明,有一种方法可以创建嵌套的可观察列表,不仅适用于 EMF 列表功能,而且适用于所有类型的可观察列表。
诀窍是对 returns 可观察列表的工厂使用 MasterDetailObservables.detailValues
方法。
Network network = TryingFactory.eINSTANCE.createNetwork();
network.getMasters().add(TryingFactory.eINSTANCE.createMaster());
network.getMasters().add(TryingFactory.eINSTANCE.createMaster());
network.getMasters().get(0).getSlaves().add(TryingFactory.eINSTANCE.createSlave());
network.getMasters().get(1).getSlaves().add(TryingFactory.eINSTANCE.createSlave());
network.getMasters().get(1).getSlaves().add(TryingFactory.eINSTANCE.createSlave());
IObservableList<Master> masterList = EMFProperties.list(Literals.NETWORK__MASTERS).observe(network);
IObservableList<IObservableList<Slave>> nestedLists = MasterDetailObservables.detailValues(masterList,
master -> Observables.constantObservableValue(masterList.getRealm(),
EMFProperties.list(Literals.MASTER__SLAVES).observe(master),
IObservableList.class),
IObservableList.class);
// Dispose nested lists when they are removed from the top-level list
nestedLists.addListChangeListener(event -> event.diff.accept(new ListDiffVisitor<IObservableList<?>>() {
@Override
public void handleRemove(int index, IObservableList<?> element) {
element.dispose();
}
@Override public void handleAdd(int index, IObservableList<?> element) {}
@Override public void handleMove(int oldIndex, int newIndex, IObservableList<?> element) {}
}));
nestedLists.forEach(System.out::println);
// Prints:
// [trying.impl.SlaveImpl@7692d9cc]
// [trying.impl.SlaveImpl@75f32542, trying.impl.SlaveImpl@7f1302d6]