何时必须调用以编程方式实例化的小部件的 startup() 方法?

Posted

技术标签:

【中文标题】何时必须调用以编程方式实例化的小部件的 startup() 方法?【英文标题】:When do I have to call the startup() method of programmatically instantiated widgets? 【发布时间】:2009-08-17 18:22:48 【问题描述】:

我从我的 JS 代码中创建了 dijit.layout.ContentPanedijit.layout.StackContainerdijit.layout.BorderContainer 的实例。

看来我必须调用以编程方式创建的实例的startup() 方法。 但是,我不确定是否必须为每个小部件调用它。 例如,当我执行“new my.foo.widget()”时,startup() 会自动触发。

感谢您帮助我了解何时调用 startup() 方法!

【问题讨论】:

【参考方案1】:

startup() 在 _Widget 中定义,只是“生命周期的一部分”。这是小部件生命周期的最后一步,并非所有小部件都需要。绝对需要它的最常见情况是在以编程方式创建布局小部件时。当孩子需要调整大小时,它被用作防止冗余计算的一种方式。例如,一个 BorderContainer。

var bc = new dijit.layout.BorderContainer( 
    style:"height:200px; width:200px" 
);

// can call bc.startup() now, and the BorderContainer will resize 
// all children each time a new child is added. Or, we can add all 
// our children now, then trigger startup() and do it all at once.

var top = new dijit.layout.ContentPane( 
    region:"top", style:"height:100px" 
).placeAt(bc);
var mid = new dijit.layout.ContentPane( region:"center" ).placeAt(bc);

// now BC will do the calculations, rather than in between each
// the above addChild/placeAt calls. 
bc.startup();

在 parseOnLoad:true 或手动执行的情况下,解析器会自动调用 Startup。解析器会延迟调用 startup(),直到所有找到的子小部件都被适当地实例化。

dijit.Dialog 是一个奇怪的例子。 startup() 也必须在这个小部件上调用。

var dialog = new dijit.Dialog( title:"Hmm", href:"foo.html" );
dialog.startup();
dialog.show(); 

大多数小部件不需要启动调用,但是在从 _Widget 继承的某些内容不覆盖启动成员的情况下,调用本质上是一个无操作设置 this._started = true;如果您创建自己的 startup() 函数,您应该调用 this.inherited(arguments) 或简单地手动设置 _started 触发器。

在 Dojo 1.4 中,这里的生命周期进行了轻微调整。以前,带有 widgetsInTemplate:true 的小部件会在父小部件上调用 startup() 之前在子小部件上调用 startup()。在 1.4 中,子代的 startup() 将在父代的 startup() 之后调用。这种行为是递归的,但是实例化了带有 widgetsInTemplate:true 的许多级别的嵌套小部件。

调用 .startup() 总是“安全”的,但如果您“知道”(因为它是一个简单的端点小部件,或者您自己的自定义 _Widget 代码),您可以省略该调用。

【讨论】:

仅供参考,行为 reg dijit.Dialog 现在调用 show 会自动从函数内部调用启动【参考方案2】:

您确定它是自动调用的,还是您的小部件中有代码调用它?

调用它是一个好习惯,因为它将_started 设置为true,很多小部件使用它来确定行为和/或布局。大多数小部件都要求您调用它(如您所见)。

startup 被需要控制子小部件的复合小部件大量使用。

基本上,从dijit._Widget 继承的任何东西都应该在实例化后调用启动。

编辑:

有一个关于 dijit 生命周期的 article on SitePen 在文章本身和 cmets 中讨论了启动。不过它已经有两年多了,我认为情况已经发生了变化。

O'Reilly dojo book 也谈到了启动,但它说应该在容器小部件上调用它。我不得不在网格上调用它,所以这也没有意义。

调用它并不会真正伤害任何东西(除非您在将子元素添加到您的小部件之前调用它)。我会说总是调用它。

【讨论】:

我刚刚重试了,你是对的。即使对于我自己的小部件,我也必须自己调用 startup()。 Dojo Campus 的 dijit.layout.ContentPane (docs.dojocampus.org/dijit/layout/ContentPane) 示例不调用 startup() 方法。这个小部件呢? 嗯,你是对的。不太清楚为什么该示例不调用启动。我只是习惯性地称呼它。

以上是关于何时必须调用以编程方式实例化的小部件的 startup() 方法?的主要内容,如果未能解决你的问题,请参考以下文章

未调用以编程方式添加的按钮操作

spring 注入 和 实例化的差别(别说没区别)

dojo中以编程方式与以声明方式创建的小部件之间的区别?

如何以编程方式将 UI 添加到基于 Qtvtkwidget 的小部件?

Spring Actuator Controller 端点在哪里,我可以使用 jvm 调用以编程方式调用它吗?

不可实例化的超类