何时使用 Seaside 组件,何时使用简单渲染对象?
我最近一直在 Seaside+Squeak 中开发一个 Web 应用程序,并发现这是一次美妙的体验。 Seaside 确实远远领先于其他所有框架,我感觉自己正在更高的抽象级别上工作(高于其他框架让您处理的 HTTP 请求/响应周期和 HTML 模板)。
也就是说,我对 Seaside 组件有点困惑。 我最近必须在组件上显示对象列表(类似于 stackoverflow 首页)。 起初,我将每个对象设为一个组件(WAComponent 的子类),但事实证明这确实很浪费,而且我必须在父组件中动态设置 #children 才能使其正常工作。 然后我尝试让它们渲染对象(不是 WAComponent 子类的对象,并使用 renderOn: 而不是 renderContentOn: 进行渲染,就像组件一样)。 这有效,但现在他们无法再像组件那样访问会话对象中的全局状态(使用#session)。 然后我发现了“WACurrentSession value”,它允许任何对象访问当前 Seaside 会话对象。 我现在能够让它们渲染对象。 此外,我发现我也可以将许多其他更次要的组件重写为渲染对象。
除了需要呼叫/应答或回溯状态之外,在渲染对象上使用组件还有什么其他原因?
I have been developing a web application in Seaside+Squeak recently, and have found it to be a wonderful experience. Seaside really is head and shoulders above every other framework out there, and I feel as though I am working at a higher level of abstraction (above the HTTP request/response cycle and HTML templating that other frameworks make you deal with).
That said, I'm a little confused about Seaside components. I recently had to display a list of objects on a component (similar to the stackoverflow front page). At first I made each object a component (a subclass of WAComponent), but this proved to be really wasteful, and I had to set #children dynamically in the parent component for it to work at all. I then tried making them render objects (objects that aren't subclasses of WAComponent, and render using renderOn: instead of renderContentOn:, like components do). This worked, but now they could no longer access global state in the session object as components can (using #session). Then I discovered "WACurrentSession value", which gives any object access to the current Seaside session object. I was now able to make them render objects. In addition, I discovered that I could rewrite a lot of my other, more minor components as render objects, too.
Besides needing call/answer or backtracking state, what other reasons are there for using components over render objects?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是 Seaside 新用户经常感到困惑的地方。 我们已经尽力在 Seaside 2.9(目前处于 Alpha 版本)中使这一点更加清晰,但我将在这里尝试重点关注 2.8,因为听起来这就是您正在使用的。
首先,您不需要使用组件来访问会话,这是正确的。 Seaside 2.9 将
#session
移至新类WAObject
,这使得几乎所有 Seaside 对象(包括组件)都可以访问它,但您绝对可以参考WACurrentSession
code> 现在在 2.8 中。组件在 2.8 中大致提供以下功能:
#renderContentOn:
使用您在#rendererClass
中指定的任何渲染器类的实例进行调用(而不是在您使用时使用的任何渲染器)。对象被要求渲染自身)#updateUrl:
),允许更新渲染器用来生成链接的 URL#updateRoot:
,# style
,#script
) 以允许更新 HTML 文档的 HEAD 部分#updateStates:
,#states
),使状态回溯更容易#initialRequest:
),允许基于导致创建会话的请求进行初始化#children< /code>),以确保下面的所有组件也将调用上面的钩子 添加
#inform:
、#isolate:
等)如果您不需要上述任何内容,则不需要组件。 如果您需要上述任何一个,那么您几乎确实需要一个组件,除非您想在自己的类上实现等效的功能。
最简单的指标可能是:如果您打算在 HTTP 请求之间保留该对象,那么它应该是一个组件; 如果您打算丢弃该对象并在每个渲染通道上创建它,则可能不需要这样做。 如果您想象一个显示博客页面的应用程序,您可能会有菜单、博客卷、博客正文、每条评论等组件。 您可能想要分解博客标记的读取和 HTML 的生成,以便您可以支持不同的标记或不同的渲染器,并且评论组件可以支持相同的标记。 这可以通过实现
#renderOn:
的非组件类来完成,并且可以根据需要由其他组件创建和使用。Seaside 2.9 目前通过使
WAPresenter
具体化并引入WAPainter
作为其超类来拆分上述功能。 上面的 1-3 是在WAPainter
上实现的,4-7 是在WAPresenter
上实现的,因此您可以根据需要选择子类化的内容。 它还从 WAPresenter 和 WAComponent 中删除了许多方法,以使最终用户更容易理解它们。希望有帮助。
This is a frequent point of confusion for new Seaside users. We have tried hard to make this clearer in Seaside 2.9, which is currently in Alpha, but I will try to focus on 2.8 here since it sounds like that is what you are using.
First of all, you are correct that you do not need to use a Component in order to access the Session. Seaside 2.9 moves
#session
up to a new classWAObject
which makes it accessible to almost all Seaside objects (including Components) but you can definitely refer toWACurrentSession
yourself for now in 2.8.Components provide roughly the following functionality in 2.8:
#renderContentOn:
is called with an instance of whatever renderer class you specify in#rendererClass
(instead of whatever renderer is in use when your object is asked to render itself)#updateUrl:
) to allow updating the URL used by the renderer to generate links#updateRoot:
,#style
,#script
) to allow updating the HEAD section of the HTML document#updateStates:
,#states
) to make state backtracking easier#initialRequest:
) to allow initialization based on the request that caused the Session to be created#children
) to make sure all components below you will also have the above hooks called on them#inform:
,#isolate:
, etc)If you don't need any of the above, you don't need a Component. If you need any of the above, you pretty much do need a Component unless you want to implement the equivalent functionality on your own class.
The simplest metric is probably: if you intend to keep the object around between HTTP requests it should be a Component; if you intend to throw the object away and create it on each rendering pass it probably doesn't need to be. If you imagine an application that was displaying blog pages, you'd probably have Components for a menu, a blog roll, the blog body, each comment, and so on. You might want to factor out the reading of the blog's markup and generation of its HTML so that you could support different markups or different renderers and so that the comment Components could support the same markup. This could be done with a non-Component class that implements
#renderOn:
and could be created and used by other Components as needed.Seaside 2.9 currently splits up the above functionality by making
WAPresenter
concrete and introducingWAPainter
as its superclass. 1-3 above are implemented onWAPainter
and 4-7 onWAPresenter
so you have your choice of what to subclass depending on your needs. It also removes a lot of methods from WAPresenter and WAComponent in an effort to make them easier for end users to understand.Hope that helps.