2009-08-17 2 views
8

Я создаю экземпляры dijit.layout.ContentPane, dijit.layout.StackContainer и dijit.layout.BorderContainer из моего кода JS.Когда мне нужно вызвать метод startup() программно созданных виджетами?

Кажется, мне нужно вызвать метод программно созданных экземпляров startup(). Однако я не уверен, что должен называть его для каждого виджета. Например, когда я делаю «new my.foo.widget()», startup() запускается автоматически.

Спасибо, что помогли мне понять, когда следует называть метод startup()!

ответ

15

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: правда или ручного исполнения. Парсер задерживает вызов startup(), пока все найденные дочерние виджеты не будут созданы соответствующим образом.

dijit.Dialog - странный случай. startup() ДОЛЖЕН быть вызван и в этом виджете.

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

Большинство виджетов не требуют запуска называется, но в тех случаях, когда что-то наследующий _Widget не перекрывающих элемента запуска, вызов по существу установка не оп this._started = истина; Если вы создаете свою собственную функцию startup(), вы должны либо вызвать this.inherited (аргументы), либо просто установить пуск _started вручную.

В Dojo 1.4 жизненный цикл здесь немного скорректирован.Раньше виджет с widgetsInTemplate: true вызывал startup() в дочерних виджетах перед запуском() родительского элемента. В 1.4 детский запуск() будет вызван ПОСЛЕ запуска родительского запуска(). Это поведение является рекурсивным для любого количества вложенных виджетов с widgetsInTemplate: true.

Это всегда «безопасно» для вызова .startup(), хотя если вы «знаете» (поскольку это простой виджет конечной точки или ваш собственный код _Widget), вы можете опустить вызов.

+1

Просто для информации поведение reg dijit.Dialog немного изменилось, теперь вызов show автоматически вызывает запуск изнутри функции – Gaurav

2

Вы уверены, что это называется автоматически или у вас есть код в своем виджете, который вызывает его?

Рекомендуется использовать его, поскольку он устанавливает _started в true, который используется довольно многими виджетами для определения поведения и/или макета. Большинство виджетов требуют, чтобы вы его вызывали (как вы видели).

startup В значительной степени используются составные виджеты, которым необходимо управлять суб-виджетами.

В принципе, все, что наследуется от dijit._Widget, должно вызвать запуск после создания экземпляра.

правок:

Там в article on SitePen о жизненном цикле Dijit который обсуждает запуск немного в самой статье и в комментариях. Это уже более двух лет, и я думаю, что все изменилось.

O'Reilly dojo book также рассказывает о запуске, но он говорит, что он должен быть вызван на виджеты keepiner. Я должен был назвать это на сетке, хотя это тоже не имеет смысла.

На самом деле это не повредит, позвонив (если вы не вызываете его, прежде чем дети будут добавлены в ваш виджет). Я бы сказал, всегда называю это.

+0

Я просто перепробовал, и вы правы. Даже для моего собственного виджета я должен сам вызвать startup(). Примеры Dojo Campus для dijit.layout.ContentPane (http://docs.dojocampus.org/dijit/layout/ContentPane) не вызывают метод startup(). Как насчет этого виджета? – Philippe

+0

Хм, ты прав. Не совсем уверен, почему запуск не вызван в этом примере. Я всегда называл это по привычке. – seth

0
startup (originating from dijit._Widget) 

Для дочерних виджетов, объявленных в разметке, этот метод автоматически запускается после создания виджета и всех дочерних виджетов. Таким образом, это первое безопасное место, где дочерний виджет может безопасно ссылаться на ребенка. Проще, как кажется, эта задача часто предпринимается в postCreate, что может привести к непоследовательному поведению, которое трудно обнаружить и восстановить. Для программно созданных виджетов, которые содержат другие дочерние виджеты как часть отношений has-a, вам нужно вручную вызвать запуск самостоятельно, если вы уверены, что все дочерние виджеты созданы. Причина, по которой вам нужно называть ее для программно созданных виджетах, содержащих детей, - это потому, что не было бы смысла продолжать калибровку и рендеринг, если бы все дочерние виджеты не были добавлены. (В противном случае вполне может быть много ложных запусков.) Этот метод является окончательным заглушкой метода, который вы можете переопределить для пользовательского поведения, возникающего при построении dijit.

 Смежные вопросы

  • Нет связанных вопросов^_^