Smalltalk 修改组件';从另一个组件获取状态

Smalltalk 修改组件';从另一个组件获取状态,smalltalk,pharo,seaside,Smalltalk,Pharo,Seaside,我试图在回调中设置子组件的父组件的实例变量。使用调试器,我可以看到实例变量在回调中设置正确,但在呈现子组件时,子组件并不反映所做的更改 那么,从seaside中的另一个组件修改组件的状态是非法的还是我做了其他错误的事情 示例代码: MyParentComponent>> initialize super initialize. child := MyChildComponent new. MyParentComponent>> renderContent

我试图在回调中设置子组件的父组件的实例变量。使用调试器,我可以看到实例变量在回调中设置正确,但在呈现子组件时,子组件并不反映所做的更改

那么,从seaside中的另一个组件修改组件的状态是非法的还是我做了其他错误的事情

示例代码:

MyParentComponent>> initialize
    super initialize.
    child := MyChildComponent new.

MyParentComponent>> renderContentOn: html 
  html render: child.   
  html anchor
     callback: [ 
        child property: 'Something'.
    ] ; with 'Navigate'.

MyParentComponent>> children 
  ^ Array with: child

我想您在父组件中错过了一些超级初始化

我也建议你不要这样工作

使用

  ^ child ifNil: [ child := MyChildComponent new ]
另外,不要执行
html呈现:child
,而是执行
html呈现:self-child
。 这样您就可以轻松地交换组件


这样,您就可以确定孩子已经正确初始化。

经过一点实验,我发现了问题。在其中一种呈现方法中,我在每次呈现页面时都创建一个新组件,而不是重用在
initialize
方法中创建的组件

另一个组件用于导航,我根据选择的菜单设置要显示的主要组件


所以很明显,在海边改变状态并不违法

这将有助于张贴代码来举例说明这个问题。我已经添加了部分代码。MyChildComponent有一个实例变量“property”,它的值用于rendering.oops,很抱歉我正确设置了super initialize。复制粘贴时出错。在Seaside中,延迟初始化不是一个好的做法。原因是渲染时不应修改组件状态。组件应完全初始化(包括子组件)。如果您使用lazy init,您将在渲染时有效地更改状态。如果我们在那里使用lazy init,子级不意味着要正确初始化它们吗?我觉得不使用self-xxx很痛苦。我在初始化方法中调用self-children以确保它们被初始化。当然,在某些情况下,这不是动态列表等的方式。修改状态在回调中不是“非法”的。它在呈现方法中是“非法的”。除了您遇到的bug之外,您还将遇到状态回溯的问题。Seaside在渲染组件之前保存组件的状态。当你做“后退”时,Seaside会恢复那种状态。在这种情况下,您将丢失这些状态更改。因此,渲染时永远不要更改状态。