如何从变形中的字典更新单个 key/value?

How to update single key/value from dictionary in morph?

中,我询问如何在 GUI 中显示 Dictionary 的内容。我从这个想法开始构建一个外观和感觉稍微好一点的 GUI。它主要由按列和行粘在一起的 RectangleMorph 组成(参见我上一个问题中接受的答案)。

现在的问题是,当我的字典中的元素为 added/removed/edited 时,我希望更新我的 table。我设法写了一些 Morph,它由 CellMorph 的列组成,它们继承自 RectangleMorph 并具有 modelmessage 作为实例变量,并进行了以下更新留言:

update
    " update the contents of this cell "

    | value |
    self removeAllMorphs.
    (model = nil or: message = nil) 
        ifTrue: [ value := '' ]
        ifFalse: [ value := model perform: message ].
    self addMorph: value asMorph.

可以看出,CellMorph 是包含单元格实际内容的 Morph 的容器。这非常适合显示字典的大小,例如:

d := Dictionary new.
d at: 'foo' put: 100.
d at: 'bar' put: 200.

cell := CellMorph new
    model: d;
    message: #size;
    color: Color white.
cell openInWorld.

d at: 'boo' put: 300.  " cell will be updated "

但我似乎没有得到类似的东西来处理字典的内容,因为我找不到通过消息访问单个键或值的方法。我能想到的唯一解决方案是每次都使用新单元格创建新列,但这太昂贵了,我无法想象这是个好主意...

因此我的问题
有没有一种方法可以在不创建数十亿个 CellMorph 的情况下更新我的 Morph 显示字典,或者我是否应该忘记我的想法,而是使用 CellMorph 的行,例如为了将字典中的条目分组?


为了完整性:CellMorph 中的 model: 消息看起来像:

model: newModel
    "change the model behind this cell"

    model ifNotNil: [ model removeDependent: self ].
    newModel ifNotNil: [newModel addDependent: self].
    model := newModel.
    self update.

update: aParameter 只是调用 update.,我还在 Dictionary 的所有消息中添加了 self changed.,我希望接口被通知(at: put:, removeKey:, 等等).

在名为 'message' 的实例变量中,您可以有一个 Message 对象,而不仅仅是选择器。 Message 的实例具有接收者、选择器和参数。因此,您可以使用接收器中的 dictionary keys sorted asArray、选择器 #at: 和索引来配置它,以获取特定的键。访问该值将在以下位置获取值:字典中的那个键。

我认为 object perform: message 没有执行消息,您应该检查一下。 message perform 应该可以工作,因为它已经有了接收器。

在任何情况下,这种复杂性可能表明只有(一个)模型和(一个)消息不足以获得您想要的粒度的模型,并且您可以利用知识进行更多专业化该模型是一本字典。例如,为 key 或 keyIndex 设置一个实例变量。

关于代码的一些旁注:

(model = nil or: message = nil) 

与 nil 进行比较,可以用 #isNil 消息替换,或者,如果您想坚持相等,请使用更快的 == 来比较标识,因为 nil 是唯一的。

#or: 用于获得部分评估的好处(仅当接收者为假时才评估参数)。但这只有在你有一个块作为参数时才有效,否则之前会计算表达式,以获取堆栈中消息的参数。