如何从变形中的字典更新单个 key/value?
How to update single key/value from dictionary in morph?
在 中,我询问如何在 GUI 中显示 Dictionary
的内容。我从这个想法开始构建一个外观和感觉稍微好一点的 GUI。它主要由按列和行粘在一起的 RectangleMorph
组成(参见我上一个问题中接受的答案)。
现在的问题是,当我的字典中的元素为 added/removed/edited 时,我希望更新我的 table。我设法写了一些 Morph
,它由 CellMorph
的列组成,它们继承自 RectangleMorph
并具有 model
和 message
作为实例变量,并进行了以下更新留言:
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:
用于获得部分评估的好处(仅当接收者为假时才评估参数)。但这只有在你有一个块作为参数时才有效,否则之前会计算表达式,以获取堆栈中消息的参数。
在 Dictionary
的内容。我从这个想法开始构建一个外观和感觉稍微好一点的 GUI。它主要由按列和行粘在一起的 RectangleMorph
组成(参见我上一个问题中接受的答案)。
现在的问题是,当我的字典中的元素为 added/removed/edited 时,我希望更新我的 table。我设法写了一些 Morph
,它由 CellMorph
的列组成,它们继承自 RectangleMorph
并具有 model
和 message
作为实例变量,并进行了以下更新留言:
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:
用于获得部分评估的好处(仅当接收者为假时才评估参数)。但这只有在你有一个块作为参数时才有效,否则之前会计算表达式,以获取堆栈中消息的参数。