X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6746dc89c47ed01b165cc1152533605f97eb8e8d..f562e4c6e5fac7bcb445985b99acbea4d706e6f0:/docs/guides/components/README.js diff --git a/docs/guides/components/README.js b/docs/guides/components/README.js index 5f40abca..bd7d7760 100644 --- a/docs/guides/components/README.js +++ b/docs/guides/components/README.js @@ -1,3 +1 @@ -Ext.data.JsonP.components({ - "guide": "

Components

\n\n
\n\n

All components in Ext JS 4 are rendered with a base div element which provides a unique id, and baseline component classes (cls, cmpCls, baseCls, and ui). If additional elements are needed to create a component, they are now handled with an XTemplate (renderTpl). Data for the XTemplate is read from a renderData object and Ext.Element references can be placed on the component instance via renderSelectors. The renderSelector is scoped from the base div element and uses standard css selectors. These Ext.Element references are part of the component lifecycle and removed automatically when the component is destroyed. The following example will help illustrate the creation of a custom component:

\n\n

Simple custom icon component example:

\n\n
IconComponent = Ext.extend(Ext.Component, {\n   iconCls: 'myIcon',\n   renderTpl: '<img alt=\"\" src=\"{blank}\" class=\"{iconCls}\"/>',\n   onRender: function() {\n       Ext.applyIf(this.renderData, {\n           blank: Ext.BLANK_IMAGE_URL,\n           iconCls: this.iconCls\n       });\n       Ext.applyIf(this.renderSelectors, {\n           iconEl: '.' + this.iconCls\n       });\n       IconComponent.superclass.onRender.call(this);\n   },\n   changeIconCls: function(newIconCls) {\n       if (this.rendered) {\n           this.iconEl.replaceClass(this.iconCls, newIconCls);\n       }\n       this.iconCls = newIconCls;\n   }\n});\n
\n\n

The renderTpl defines an XTemplate with \"blank\" and \"iconCls\" variables which are read from renderData at render time. In addition, an \"iconEl\" reference to the Ext.Element is applied to the instance at render time. The changeIconCls method can now use the iconEl as soon as the component has been rendered.

\n\n\n\n\n\n\n\n\n\n\n\n\n\n" -}); \ No newline at end of file +Ext.data.JsonP.components({"guide":"

Components

\n\n
\n\n

An Ext JS application's UI is made up of one or many widgets called Components. All Components are subclasses of the Ext.Component class\nwhich allows them to participate in automated lifecycle management including instantiation, rendering, sizing and positioning, and destruction.\nExt JS provides a wide range of useful Components out of the box, and any Component can easily be extended to create a customized Component.

\n\n

The Component Hierarchy

\n\n

A Container is a special type of Component that can contain other Components. A typical application is made up of many nested Components in a tree-like\nstructure that is referred to as the Component hierarchy. Containers are responsible for managing the Component lifecycle of their children, which includes creation, rendering,\nsizing and positioning, and destruction. A typical application's Component hierarchy starts with a Viewport at the top,\nwhich has other Containers and/or Components nested within it:

\n\n

\"Component

\n\n

Child Components are added to a Container using the Container's items configuration property. This example uses Ext.create\nto instantiate two Panels, then adds those Panels as child Components of a Viewport:

\n\n
var childPanel1 = Ext.create('Ext.panel.Panel', {\n    title: 'Child Panel 1',\n    html: 'A Panel'\n});\n\nvar childPanel2 = Ext.create('Ext.panel.Panel', {\n    title: 'Child Panel 2',\n    html: 'Another Panel'\n});\n\nExt.create('Ext.container.Viewport', {\n    items: [ childPanel1, childPanel2 ]\n});\n
\n\n

Containers use Layout Managers to size and position their child Components.\nFor more information on Layouts and Containers please refer to the Layouts and Containers Guide.

\n\n

See the Container Example for a working demo showing how to add Components to a Container using the items configuration.

\n\n

XTypes and Lazy Instantiation

\n\n

Every Component has a symbolic name called an xtype. For example Ext.panel.Panel has an xtype of 'panel'.\nThe xtypes for all Components are listed in the API Docs for Component.\nThe above example showed how to add already instantiated Components to a Container.\nIn a large application, however, this is not ideal since not all of the Components need to be instantiated right away,\nand some Components might never be instantiated depending on how the application is used. For example an application that uses a Tab Panel\nwill only need the contents of each tab to be rendered if and when each tab is clicked on by the user. This is where xtypes come in handy\nby allowing a Container's children to be configured up front, but not instantiated until the Container determines it is necessary.

\n\n

The following example code demonstrates lazy instantiation and rendering of a Container's Child components using a Tab Panel.\nEach tab has an event listener that displays an alert when the tab is rendered.

\n\n
Ext.create('Ext.tab.Panel', {\n    renderTo: Ext.getBody(),\n    height: 100,\n    width: 200,\n    items: [\n        {\n            // Explicitly define the xtype of this Component configuration.\n            // This tells the Container (the tab panel in this case)\n            // to instantiate a Ext.panel.Panel when it deems necessary\n            xtype: 'panel',\n            title: 'Tab One',\n            html: 'The first tab',\n            listeners: {\n                render: function() {\n                    Ext.MessageBox.alert('Rendered One', 'Tab One was rendered.');\n                }\n            }\n        },\n        {\n            // this component configuration does not have an xtype since 'panel' is the default\n            // xtype for all Component configurations in a Container\n            title: 'Tab Two',\n            html: 'The second tab',\n            listeners: {\n                render: function() {\n                    Ext.MessageBox.alert('Rendered One', 'Tab Two was rendered.');\n                }\n            }\n        }\n    ]\n});\n
\n\n

Running this code results in an immediate alert for the first tab. This happens because it is the default active tab,\nand so its Container Tab Panel instantiates and renders it immediately.

\n\n

\"Lazy

\n\n

The alert for the second tab does not get displayed until the tab is clicked on. This shows that the tab was not rendered until\nneeded, since the render event did not fire until the tab was activated.

\n\n

\"Lazy

\n\n

For a working demo see the Lazy Instantiation Example

\n\n

Showing and Hiding

\n\n

All Components have built in show and hide methods.\nThe default CSS method used to hide the Component is \"display: none\", but this can be changed using the hideMode configuration:

\n\n
var panel = Ext.create('Ext.panel.Panel', {\n    renderTo: Ext.getBody(),\n    title: 'Test',\n    html: 'Test Panel',\n    hideMode: 'visibility' // use the CSS visibility property to show and hide this component\n});\n\npanel.hide(); // hide the component\n\npanel.show(); // show the component\n
\n\n

Floating Components

\n\n

Floating Component are positioned outside of the document flow using CSS absolute positioning, and do not participate in their Containers' layout.\nSome Components such as Windows are floating by default, but any Component can be made floating using the floating configuration.

\n\n
var panel = Ext.create('Ext.panel.Panel', {\n    width: 200,\n    height: 100,\n    floating: true, // make this panel an absolutely-positioned floating component\n    title: 'Test',\n    html: 'Test Panel'\n});\n
\n\n

The above code instantiates a Panel but does not render it. Normally a Component either has a renderTo\nconfiguration specified, or is added as a child Component of a Container, but in the case of floating Components neither of these is needed.\nFloating Components are automatically rendered to the document body the first time their show method is called:

\n\n
panel.show(); // render and show the floating panel\n
\n\n

Here are a few other configurations and methods to make note of related to floating components:

\n\n\n\n\n

For a working demo of floating Component features see the Floating Panel Example.

\n\n

Creating Custom Components

\n\n

Composition or Extension

\n\n

When creating a new UI class, the decision must be made whether that class should own an instance of a Component, or to extend that Component.

\n\n

It is recommended to extend the nearest base class to the functionality required. This is because of the automated lifecycle management Ext JS provides which\nincludes automated rendering when needed, automatic sizing and positioning of Components when managed by an appropriate layout manager,\nand automated destruction on removal from a Container.

\n\n

It is easier to write a new class which is a Component and can take its place in the Component hierarchy rather than a new class which has an Ext JS Component,\nand then has to render and manage it from outside.

\n\n

Subclassing

\n\n

The Class System makes it easy to extend existing Components. The following example creates a subclass of Ext.Component without\nadding any additional functionality:

\n\n
Ext.define('My.custom.Component', {\n    extend: 'Ext.Component'\n});\n
\n\n

Template Methods

\n\n

Ext JS uses the Template method pattern to delegate to subclasses, behavior which is specific only to that subclass.

\n\n

The meaning of this is that each class in the inheritance chain may \"contribute\" an extra piece of logic to certain phases in the Component's lifecycle.\nEach class implements its own special behavior while allowing the other classes in the inheritance chain to continue to contribute their own logic.

\n\n

An example is the render function. render is a private method defined in Component's superclass,\nAbstractComponent that is responsible for initiating the rendering phase of the Component lifecycle.\nrender must not be overridden, but it calls onRender during processing to allow the subclass implementor to add an onRender\nmethod to perform class-specific processing. Every onRender method must call its superclass' onRender method before \"contributing\" its extra logic.

\n\n

The diagram below illustrates the functioning of the onRender template method.

\n\n

The render method is called (This is done by a Container’s layout manager). This method may not be overridden and is implemented by the Ext base class.\nIt calls this.onRender which is the implementation within the current subclass (if implemented).\nThis calls the superclass version which calls its superclass version etc. Eventually, each class has contributed its functionality, and control returns to the render function.

\n\n

\"Template

\n\n

Here is an example of a Component subclass that implements the onRender method:

\n\n
Ext.define('My.custom.Component', {\n    extend: 'Ext.Component',\n    onRender: function() {\n        this.callParent(arguments); // call the superclass onRender method\n\n        // perform additional rendering tasks here.\n    }\n});\n
\n\n

It is important to note that many of the template methods also have a corresponding event. For example the render\nevent is fired after the Component is rendered. When subclassing, however, it is it is essential to use template methods to perform class logic at\nimportant phases in the lifecycle and not events. Events may be programmatically suspended, or may be stopped by a handler.

\n\n

Below are the template methods that can be implemented by subclasses of Component:

\n\n\n\n\n

Which Class To Extend

\n\n

Choosing the best class to extend is mainly a matter of efficiency, and which capabilities the base class must provide.\nThere has been a tendency to always extend Ext.Panel whenever any set of UI Components needs to be rendered and managed.

\n\n

The Panel class has many capabilities:

\n\n\n\n\n

If these are not needed, then using a Panel is a waste of resources.

\n\n

Component

\n\n

If the required UI Component does not need to contain any other Components, that is, if it just to encapsulate some form of HTML which performs the requirements,\nthen extending Ext.Component is appropriate. For example, the following class is a Component that wraps an HTML image element, and allows setting\nand getting of the image's src attribute. It also fires a load event when the image is loaded:

\n\n
Ext.define('Ext.ux.Image', {\n    extend: 'Ext.Component', // subclass Ext.Component\n    alias: 'widget.managedimage', // this component will have an xtype of 'managedimage'\n    autoEl: {\n        tag: 'img',\n        src: Ext.BLANK_IMAGE_URL,\n        cls: 'my-managed-image'\n    },\n\n    // Add custom processing to the onRender phase.\n    // Add a ‘load’ listener to the element.\n    onRender: function() {\n        this.autoEl = Ext.apply({}, this.initialConfig, this.autoEl);\n        this.callParent(arguments);\n        this.el.on('load', this.onLoad, this);\n    },\n\n    onLoad: function() {\n        this.fireEvent('load', this);\n    },\n\n    setSrc: function(src) {\n        if (this.rendered) {\n            this.el.dom.src = src;\n        } else {\n            this.src = src;\n        }\n    },\n\n    getSrc: function(src) {\n        return this.el.dom.src || this.src;\n    }\n});\n
\n\n

Usage:

\n\n
var image = Ext.create('Ext.ux.Image');\n\nExt.create('Ext.panel.Panel', {\n    title: 'Image Panel',\n    height: 200,\n    renderTo: Ext.getBody(),\n    items: [ image ]\n})\n\nimage.on('load', function() {\n    console.log('image loaded: ', image.getSrc());\n});\n\nimage.setSrc('http://www.sencha.com/img/sencha-large.png');\n
\n\n

See the Managed Image Example for a working demo. This example is for demonstration purposes only -\nthe Ext.Img class should be used for managing images in a real world application.

\n\n

Container

\n\n

If the required UI Component is to contain other Components, but does not need any of the previously mentioned additional capabilities of a Panel,\nthen Ext.container.Container is the appropriate class to extend. At the Container level, it is important to remember which Layout\nis to be used to render and manage child Components.

\n\n

Containers have the following additional template methods:

\n\n\n\n\n

Panel

\n\n

If the required UI Component must have a header, footer, or toolbars, then Ext.Panel is the appropriate class to extend.

\n\n

Important: A Panel is a Container. It is important to remember which Layout is to be used to render and manage child Components.

\n\n

Classes which extend Ext.Panel are usually highly application-specific and are generally used to aggregate other UI Components\n(Usually Containers, or form Fields) in a configured layout, and provide means to operate on the contained Components by means\nof controls in the tbar and the bbar.

\n\n

Panels have the following additional template methods:

\n\n\n\n","title":"Components"}); \ No newline at end of file