【问题标题】:Modifying a component's state from another component从另一个组件修改组件的状态
【发布时间】:2013-10-09 10:38:04
【问题描述】:

我正在尝试从回调中的父组件设置子组件的实例变量。使用调试器我可以看到实例变量在回调中设置正确,但是在渲染子组件时,子组件没有反映所做的更改。

那么,在海边从另一个组件修改组件的状态是违法的还是我做错了什么?

示例代码:

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

【问题讨论】:

  • 这将有助于发布示例问题的代码。
  • 我添加了一部分代码。 MyChildComponent 有一个实例变量“property”,它的值用于渲染。

标签: smalltalk pharo seaside


【解决方案1】:

我猜你在父组件中错过了一些super initialize

我也建议你不要这样工作。

使用MyParentComponent>>child

  ^ child ifNil: [ child := MyChildComponent new ]

另外,不要使用html render: child,而是使用html render: self child。 这样您就可以轻松地交换组件。

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

【讨论】:

  • 哎呀,对不起,我正确设置了超级初始化。复制粘贴时出错。
  • 延迟初始化在 Seaside 中不是一个好习惯。原因是您不应该在渲染时修改组件状态。组件应完全初始化(包括子组件)。如果你使用惰性初始化,你将在渲染时有效地改变状态。
  • 如果我们在那里使用惰性初始化,孩子不应该让他们正确初始化吗?我觉得不使用 self xxx 很痛苦。以防万一我需要在开发过程中进行更改。
  • 我在我的初始化方法中调用 self children 以确保它们被初始化。当然,在某些情况下,这不是动态列表等的方式。
【解决方案2】:

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

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

显然,修改状态在 Seaside 中并不违法。

【讨论】:

  • 在回调中修改状态不是“非法的”。它在渲染方法中是“非法的”。除了您遇到的错误之外,您还会遇到状态回溯的问题。 Seaside 在渲染组件之前会保存组件的状态。当您执行“返回”时,Seaside 会恢复该状态。在这种情况下,您将丢失这些状态更改。所以永远不要在渲染时改变状态。
猜你喜欢
  • 2021-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-01
  • 2020-10-12
  • 2020-06-05
  • 2019-12-11
相关资源
最近更新 更多