Ext.data.JsonP.Ext_layout_Context({"alternateClassNames":[],"aliases":{},"enum":null,"parentMixins":[],"tagname":"class","subclasses":[],"extends":"Ext.Base","uses":[],"html":"
Hierarchy
Ext.BaseExt.layout.ContextRequires
Files
NOTE This is a private utility class for internal use by the framework. Don't rely on its existence.
Manages context information during a layout.
\n\nThis class performs the following jobs:
\n\nWork done during layout falls into either a \"read phase\" or a \"write phase\" and it is\nessential to always be aware of the current phase. Most methods in\nLayout are called during a read phase:\ncalculate,\ncompleteLayout and\nfinalizeLayout. The exceptions to this are\nbeginLayout,\nbeginLayoutCycle and\nfinishedLayout which are called during\na write phase. While finishedLayout is called\na write phase, it is really intended to be a catch-all for post-processing after a\nlayout run.
\n\nIn a read phase, it is OK to read the DOM but this should be done using the appropriate\nContextItem where possible since that provides a cache\nto avoid redundant reads. No writes should be made to the DOM in a read phase! Instead,\nthe values should be written to the proper ContextItem for later write-back.
\n\nThe rules flip-flop in a write phase. The only difference is that ContextItem methods\nlike getStyle will still read the DOM unless the\nvalue was previously read. This detail is unknowable from the outside of ContextItem, so\nread calls to ContextItem should also be avoided in a write phase.
\n\nCalculating interdependent layouts requires a certain amount of iteration. In a given\ncycle, some layouts will contribute results that allow other layouts to proceed. The\ngeneral flow then is to gather all of the layouts (both component and container) in a\ncomponent tree and queue them all for processing. The initial queue order is bottom-up\nand component layout first, then container layout (if applicable) for each component.
\n\nThis initial step also calls the beginLayout method on all layouts to clear any values\nfrom the DOM that might interfere with calculations and measurements. In other words,\nthis is a \"write phase\" and reads from the DOM should be strictly avoided.
\n\nNext the layout enters into its iterations or \"cycles\". Each cycle consists of calling\nthe calculate method on all layouts in the\nlayoutQueue. These calls are part of a \"read phase\" and writes to the DOM should\nbe strictly avoided.
\n\nRULE 1: Respect the read/write cycles. Always use the getProp\nor getDomProp methods to get calculated values;\nonly use the getStyle method to read styles; use\nsetProp to set DOM values. Some reads will, of\ncourse, still go directly to the DOM, but if there is a method in\nContextItem to do a certain job, it should be used instead\nof a lower-level equivalent.
\n\nThe basic logic flow in calculate consists of gathering\nvalues by calling getProp or\ngetDomProp, calculating results and publishing\nthem by calling setProp. It is important to realize\nthat getProp will return undefined
if the value\nis not yet known. But the act of calling the method is enough to track the fact that the\ncalling layout depends (in some way) on this value. In other words, the calling layout is\n\"triggered\" by the properties it requests.
RULE 2: Avoid calling getProp unless the value\nis needed. Gratuitous calls cause inefficiency because the layout will appear to depend on\nvalues that it never actually uses. This applies equally to\ngetDomProp and the test-only methods\nhasProp and hasDomProp.
\n\nBecause getProp can return undefined
, it is often\nthe case that subsequent math will produce NaN's. This is usually not a problem as the\nNaN's simply propagate along and result in final results that are NaN. Both undefined
\nand NaN are ignored by Ext.layout.ContextItem.setProp, so it is often not necessary\nto even know that this is happening. It does become important for determining if a layout\nis not done or if it might lead to publishing an incorrect (but not NaN or undefined
)\nvalue.
RULE 3: If a layout has not calculated all the values it is required to calculate, it\nmust set done to false
before returning from\ncalculate. This value is always true
on entry because\nit is simpler to detect the incomplete state rather than the complete state (especially up\nand down a class hierarchy).
RULE 4: A layout must never publish an incomplete (wrong) result. Doing so would cause\ndependent layouts to run their calculations on those wrong values, producing more wrong\nvalues and some layouts may even incorrectly flag themselves as done\nbefore the correct values are determined and republished. Doing this will poison the\ncalculations.
\n\nRULE 5: Each value should only be published by one layout. If multiple layouts attempt\nto publish the same values, it would be nearly impossible to avoid breaking RULE 4. To\nhelp detect this problem, the layout diagnostics will trap on an attempt to set a value\nfrom different layouts.
\n\nComplex layouts can produce many results as part of their calculations. These values are\nimportant for other layouts to proceed and need to be published by the earliest possible\ncall to Ext.layout.Layout.calculate to avoid unnecessary cycles and poor performance. It is\nalso possible, however, for some results to be related in a way such that publishing them\nmay be an all-or-none proposition (typically to avoid breaking RULE 4).
\n\nRULE 6: Publish results as soon as they are known to be correct rather than wait for\nall values to be calculated. Waiting for everything to be complete can lead to deadlock.\nThe key here is not to forget RULE 4 in the process.
\n\nSome layouts depend on certain critical values as part of their calculations. For example,\nHBox depends on width and cannot do anything until the width is known. In these cases, it\nis best to use block or\ndomBlock and thereby avoid processing the layout\nuntil the needed value is available.
\n\nRULE 7: Use block or\ndomBlock when values are required to make progress.\nThis will mimize wasted recalculations.
\n\nRULE 8: Blocks should only be used when no forward progress can be made. If even one\nvalue could still be calculated, a block could result in a deadlock.
\n\nHistorically, layouts have been invoked directly by component code, sometimes in places\nlike an afterLayout
method for a child component. With the flexibility now available\nto solve complex, iterative issues, such things should be done in a responsible layout\n(be it component or container).
RULE 9: Use layouts to solve layout issues and don't wait for the layout to finish to\nperform further layouts. This is especially important now that layouts process entire\ncomponent trees and not each layout in isolation.
\n\nThe simplest sequence diagram for a layout run looks roughly like this:
\n\n Context Layout 1 Item 1 Layout 2 Item 2\n | | | | |\n---->X-------------->X | | |\nrun X---------------|-----------|---------->X |\n X beginLayout | | | |\n X | | | |\n A X-------------->X | | |\n X calculate X---------->X | |\n X C X getProp | | |\n B X X---------->X | |\n X | setProp | | |\n X | | | |\n D X---------------|-----------|---------->X |\n X calculate | | X---------->X\n X | | | setProp |\n E X | | | |\n X---------------|-----------|---------->X |\n X completeLayout| | F | |\n X | | | |\n G X | | | |\n H X-------------->X | | |\n X calculate X---------->X | |\n X I X getProp | | |\n X X---------->X | |\n X | setProp | | |\n J X-------------->X | | |\n X completeLayout| | | |\n X | | | |\n K X-------------->X | | |\n X---------------|-----------|---------->X |\n X finalizeLayout| | | |\n X | | | |\n L X-------------->X | | |\n X---------------|-----------|---------->X |\n X finishedLayout| | | |\n X | | | |\n M X-------------->X | | |\n X---------------|-----------|---------->X |\n X notifyOwner | | | |\n N | | | | |\n - - - - -\n
\n\nNotes:
\n\nA. This is a call from the run method to the runCycle method.\nEach layout in the queue will have its calculate\nmethod called.
\n\nB. After each calculate method is called the\ndone flag is checked to see if the Layout has completed.\nIf it has completed and that layout object implements a\ncompleteLayout method, this layout is queued to\nreceive its call. Otherwise, the layout will be queued again unless there are blocks or\ntriggers that govern its requeueing.
\n\nC. The call to getProp is made to the Item\nand that will be tracked as a trigger (keyed by the name of the property being requested).\nChanges to this property will cause this layout to be requeued. The call to\nsetProp will place a value in the item and not\ndirectly into the DOM.
\n\nD. Call the other layouts now in the first cycle (repeat B and C for each\nlayout).
\n\nE. After completing a cycle, if progress was made (new properties were written to\nthe context) and if the layoutQueue is not empty, the next cycle is run. If no\nprogress was made or no layouts are ready to run, all buffered values are written to\nthe DOM (a flush).
\n\nF. After flushing, any layouts that were marked as done\nthat also have a completeLayout method are called.\nThis can cause them to become no longer done (see invalidate). As with\ncalculate, this is considered a \"read phase\" and\ndirect DOM writes should be avoided.
\n\nG. Flushing and calling any pending completeLayout\nmethods will likely trigger layouts that called getDomProp\nand unblock layouts that have called domBlock.\nThese variants are used when a layout needs the value to be correct in the DOM and not\nsimply known. If this does not cause at least one layout to enter the queue, we have a\nlayout FAILURE. Otherwise, we continue with the next cycle.
\n\nH. Call calculate on any layouts in the queue\nat the start of this cycle. Just a repeat of B through G.
\n\nI. Once the layout has calculated all that it is resposible for, it can leave itself\nin the done state. This is the value on entry to\ncalculate and must be cleared in that call if the\nlayout has more work to do.
\n\nJ. Now that all layouts are done, flush any DOM values and\ncompleteLayout calls. This can again cause\nlayouts to become not done, and so we will be back on another cycle if that happens.
\n\nK. After all layouts are done, call the finalizeLayout\nmethod on any layouts that have one. As with completeLayout,\nthis can cause layouts to become no longer done. This is less desirable than using\ncompleteLayout because it will cause all\nfinalizeLayout methods to be called again\nwhen we think things are all wrapped up.
\n\nL. After finishing the last iteration, layouts that have a\nfinishedLayout method will be called. This\ncall will only happen once per run and cannot cause layouts to be run further.
\n\nM. After calling finahedLayout, layouts that have a\nnotifyOwner method will be called. This\ncall will only happen once per run and cannot cause layouts to be run further.
\n\nN. One last flush to make sure everything has been written to the DOM.
\n\nMany layout problems require collaboration between multiple layouts. In some cases, this\nis as simple as a component's container layout providing results used by its component\nlayout or vise-versa. A slightly more distant collaboration occurs in a box layout when\nstretchmax is used: the child item's component layout provides results that are consumed\nby the ownerCt's box layout to determine the size of the children.
\n\nThe various forms of interdependence between a container and its children are described by\neach components' size model.
\n\nTo facilitate this collaboration, the following pairs of properties are published to the\ncomponent's ContextItem:
\n\nDefined in override Ext.diag.layout.Context.
\nDefaults to: {0: 0}
Get the reference to the current class from which this object was instantiated. Unlike statics,\nthis.self
is scope-dependent and it's meant to be used for dynamic inheritance. See statics\nfor a detailed comparison
Ext.define('My.Cat', {\n statics: {\n speciesName: 'Cat' // My.Cat.speciesName = 'Cat'\n },\n\n constructor: function() {\n alert(this.self.speciesName); // dependent on 'this'\n },\n\n clone: function() {\n return new this.self();\n }\n});\n\n\nExt.define('My.SnowLeopard', {\n extend: 'My.Cat',\n statics: {\n speciesName: 'Snow Leopard' // My.SnowLeopard.speciesName = 'Snow Leopard'\n }\n});\n\nvar cat = new My.Cat(); // alerts 'Cat'\nvar snowLeopard = new My.SnowLeopard(); // alerts 'Snow Leopard'\n\nvar clone = snowLeopard.clone();\nalert(Ext.getClassName(clone)); // alerts 'My.SnowLeopard'\n
\nCall the original method that was previously overridden with override
\n\nExt.define('My.Cat', {\n constructor: function() {\n alert(\"I'm a cat!\");\n }\n});\n\nMy.Cat.override({\n constructor: function() {\n alert(\"I'm going to be a cat!\");\n\n this.callOverridden();\n\n alert(\"Meeeeoooowwww\");\n }\n});\n\nvar kitty = new My.Cat(); // alerts \"I'm going to be a cat!\"\n // alerts \"I'm a cat!\"\n // alerts \"Meeeeoooowwww\"\n
\n This method has been deprecated
\nas of 4.1. Use callParent instead.
\n\nThe arguments, either an array or the arguments
object\nfrom the current method, for example: this.callOverridden(arguments)
Returns the result of calling the overridden method
\nCall the \"parent\" method of the current method. That is the method previously\noverridden by derivation or by an override (see Ext.define).
\n\n Ext.define('My.Base', {\n constructor: function (x) {\n this.x = x;\n },\n\n statics: {\n method: function (x) {\n return x;\n }\n }\n });\n\n Ext.define('My.Derived', {\n extend: 'My.Base',\n\n constructor: function () {\n this.callParent([21]);\n }\n });\n\n var obj = new My.Derived();\n\n alert(obj.x); // alerts 21\n
\n\nThis can be used with an override as follows:
\n\n Ext.define('My.DerivedOverride', {\n override: 'My.Derived',\n\n constructor: function (x) {\n this.callParent([x*2]); // calls original My.Derived constructor\n }\n });\n\n var obj = new My.Derived();\n\n alert(obj.x); // now alerts 42\n
\n\nThis also works with static methods.
\n\n Ext.define('My.Derived2', {\n extend: 'My.Base',\n\n statics: {\n method: function (x) {\n return this.callParent([x*2]); // calls My.Base.method\n }\n }\n });\n\n alert(My.Base.method(10); // alerts 10\n alert(My.Derived2.method(10); // alerts 20\n
\n\nLastly, it also works with overridden static methods.
\n\n Ext.define('My.Derived2Override', {\n override: 'My.Derived2',\n\n statics: {\n method: function (x) {\n return this.callParent([x*2]); // calls My.Derived2.method\n }\n }\n });\n\n alert(My.Derived2.method(10); // now alerts 40\n
\n\nTo override a method and replace it and also call the superclass method, use\ncallSuper. This is often done to patch a method to fix a bug.
\nThe arguments, either an array or the arguments
object\nfrom the current method, for example: this.callParent(arguments)
Returns the result of calling the parent method
\nThis method is used by an override to call the superclass method but bypass any\noverridden method. This is often done to \"patch\" a method that contains a bug\nbut for whatever reason cannot be fixed directly.
\n\nConsider:
\n\n Ext.define('Ext.some.Class', {\n method: function () {\n console.log('Good');\n }\n });\n\n Ext.define('Ext.some.DerivedClass', {\n method: function () {\n console.log('Bad');\n\n // ... logic but with a bug ...\n\n this.callParent();\n }\n });\n
\n\nTo patch the bug in DerivedClass.method
, the typical solution is to create an\noverride:
Ext.define('App.paches.DerivedClass', {\n override: 'Ext.some.DerivedClass',\n\n method: function () {\n console.log('Fixed');\n\n // ... logic but with bug fixed ...\n\n this.callSuper();\n }\n });\n
\n\nThe patch method cannot use callParent
to call the superclass method
since\nthat would call the overridden method containing the bug. In other words, the\nabove patch would only produce \"Fixed\" then \"Good\" in the console log, whereas,\nusing callParent
would produce \"Fixed\" then \"Bad\" then \"Good\".
The arguments, either an array or the arguments
object\nfrom the current method, for example: this.callSuper(arguments)
Returns the result of calling the superclass method
\nDefined in override Ext.diag.layout.Context.
\nFlushes any pending writes to the DOM by calling each ContextItem in the flushQueue.
\n\nOverridden in Ext.diag.layout.Context.
\nOverridden in Ext.diag.layout.Context.
\nReturns the ContextItem for a component.
\n\nOverridden in Ext.diag.layout.Context.
\nReturns the ContextItem for an element.
\n\nOverridden in Ext.diag.layout.Context.
\nInitialize configuration for this class. a typical example:
\n\nExt.define('My.awesome.Class', {\n // The default config\n config: {\n name: 'Awesome',\n isAwesome: true\n },\n\n constructor: function(config) {\n this.initConfig(config);\n }\n});\n\nvar awesome = new My.awesome.Class({\n name: 'Super Awesome'\n});\n\nalert(awesome.getName()); // 'Super Awesome'\n
\nthis
\nInvalidates one or more components' layouts (component and container). This can be\ncalled before run to identify the components that need layout or during the run to\nrestart the layout of a component. This is called internally to flush any queued\ninvalidations at the start of a cycle. If called during a run, it is not expected\nthat new components will be introduced to the layout.
\nAn array of Components or a single Component.
\nTrue if all properties should be invalidated, otherwise only\n those calculated by the component should be invalidated.
\nQueues a ContextItem to have its Ext.layout.ContextItem.flushAnimations method called.
\nQueues a layout to have its Ext.layout.Layout.completeLayout method called.
\nQueues a layout to have its Ext.layout.Layout.finalizeLayout method called.
\nQueues a ContextItem for the next flush to the DOM. This should only be called by\nthe Ext.layout.ContextItem class.
\nQueue a component (and its tree) to be invalidated on the next cycle.
\nThe component or ContextItem to invalidate.
\nAn object describing how to handle the invalidation (see\n Ext.layout.ContextItem.invalidate for details).
\nQueues a layout for the next calculation cycle. This should not be called if the\nlayout is done, blocked or already in the queue. The only classes that should call\nthis method are this class and Ext.layout.ContextItem.
\n\nOverridden in Ext.diag.layout.Context.
\nThe layout to add to the queue.
\nRemoves the ContextItem for an element from the cache and from the parent's\n\"children\" array.
\nResets the given layout object. This is called at the start of the run and can also\nbe called during the run by calling invalidate.
\n\nOverridden in Ext.diag.layout.Context.
\nRuns the layout calculations. This can be called only once on this object.
\n\nOverridden in Ext.diag.layout.Context.
\nTrue if all layouts were completed, false if not.
\nPerforms one layout cycle by calling each layout in the layout queue.
\n\nOverridden in Ext.diag.layout.Context.
\nTrue if some progress was made, false if not.
\nRuns one layout as part of a cycle.
\n\nOverridden in Ext.diag.layout.Context.
\nSet the size of a component, element or composite or an array of components or elements.
\nThe item(s) to size.
\nThe new width to set (ignored if undefined or NaN).
\nThe new height to set (ignored if undefined or NaN).
\nGet the reference to the class from which this object was instantiated. Note that unlike self,\nthis.statics()
is scope-independent and it always returns the class from which it was called, regardless of what\nthis
points to during run-time
Ext.define('My.Cat', {\n statics: {\n totalCreated: 0,\n speciesName: 'Cat' // My.Cat.speciesName = 'Cat'\n },\n\n constructor: function() {\n var statics = this.statics();\n\n alert(statics.speciesName); // always equals to 'Cat' no matter what 'this' refers to\n // equivalent to: My.Cat.speciesName\n\n alert(this.self.speciesName); // dependent on 'this'\n\n statics.totalCreated++;\n },\n\n clone: function() {\n var cloned = new this.self; // dependent on 'this'\n\n cloned.groupName = this.statics().speciesName; // equivalent to: My.Cat.speciesName\n\n return cloned;\n }\n});\n\n\nExt.define('My.SnowLeopard', {\n extend: 'My.Cat',\n\n statics: {\n speciesName: 'Snow Leopard' // My.SnowLeopard.speciesName = 'Snow Leopard'\n },\n\n constructor: function() {\n this.callParent();\n }\n});\n\nvar cat = new My.Cat(); // alerts 'Cat', then alerts 'Cat'\n\nvar snowLeopard = new My.SnowLeopard(); // alerts 'Cat', then alerts 'Snow Leopard'\n\nvar clone = snowLeopard.clone();\nalert(Ext.getClassName(clone)); // alerts 'My.SnowLeopard'\nalert(clone.groupName); // alerts 'Cat'\n\nalert(My.Cat.totalCreated); // alerts 3\n
\nAdd methods / properties to the prototype of this class.
\n\nExt.define('My.awesome.Cat', {\n constructor: function() {\n ...\n }\n});\n\n My.awesome.Cat.addMembers({\n meow: function() {\n alert('Meowww...');\n }\n });\n\n var kitty = new My.awesome.Cat;\n kitty.meow();\n
\nAdd / override static properties of this class.
\n\nExt.define('My.cool.Class', {\n ...\n});\n\nMy.cool.Class.addStatics({\n someProperty: 'someValue', // My.cool.Class.someProperty = 'someValue'\n method1: function() { ... }, // My.cool.Class.method1 = function() { ... };\n method2: function() { ... } // My.cool.Class.method2 = function() { ... };\n});\n
\nthis
\nBorrow another class' members to the prototype of this class.
\n\nExt.define('Bank', {\n money: '$$$',\n printMoney: function() {\n alert('$$$$$$$');\n }\n});\n\nExt.define('Thief', {\n ...\n});\n\nThief.borrow(Bank, ['money', 'printMoney']);\n\nvar steve = new Thief();\n\nalert(steve.money); // alerts '$$$'\nsteve.printMoney(); // alerts '$$$$$$$'\n
\nThe class to borrow members from
\nThe names of the members to borrow
\nthis
\nCreate a new instance of this Class.
\n\nExt.define('My.cool.Class', {\n ...\n});\n\nMy.cool.Class.create({\n someConfig: true\n});\n
\n\nAll parameters are passed to the constructor of the class.
\nthe created instance.
\nCreate aliases for existing prototype methods. Example:
\n\nExt.define('My.cool.Class', {\n method1: function() { ... },\n method2: function() { ... }\n});\n\nvar test = new My.cool.Class();\n\nMy.cool.Class.createAlias({\n method3: 'method1',\n method4: 'method2'\n});\n\ntest.method3(); // test.method1()\n\nMy.cool.Class.createAlias('method5', 'method3');\n\ntest.method5(); // test.method3() -> test.method1()\n
\nThe new method name, or an object to set multiple aliases. See\nflexSetter
\nThe original method name
\nGet the current class' name in string format.
\n\nExt.define('My.cool.Class', {\n constructor: function() {\n alert(this.self.getName()); // alerts 'My.cool.Class'\n }\n});\n\nMy.cool.Class.getName(); // 'My.cool.Class'\n
\nclassName
\nAdds members to class.
\nThis method has been deprecated since 4.1
\nUse addMembers instead.
\n\nOverride members of this class. Overridden methods can be invoked via\ncallParent.
\n\nExt.define('My.Cat', {\n constructor: function() {\n alert(\"I'm a cat!\");\n }\n});\n\nMy.Cat.override({\n constructor: function() {\n alert(\"I'm going to be a cat!\");\n\n this.callParent(arguments);\n\n alert(\"Meeeeoooowwww\");\n }\n});\n\nvar kitty = new My.Cat(); // alerts \"I'm going to be a cat!\"\n // alerts \"I'm a cat!\"\n // alerts \"Meeeeoooowwww\"\n
\n\nAs of 4.1, direct use of this method is deprecated. Use Ext.define\ninstead:
\n\nExt.define('My.CatOverride', {\n override: 'My.Cat',\n constructor: function() {\n alert(\"I'm going to be a cat!\");\n\n this.callParent(arguments);\n\n alert(\"Meeeeoooowwww\");\n }\n});\n
\n\nThe above accomplishes the same result but can be managed by the Ext.Loader\nwhich can properly order the override and its target class and the build process\ncan determine whether the override is needed based on the required state of the\ntarget class (My.Cat).
\nThis method has been deprecated since 4.1.0
\nUse Ext.define instead
\n\nThe properties to add to this class. This should be\nspecified as an object literal containing one or more properties.
\nthis class
\n