Not Using requires in extjs has no loading effect - extjs

I am using CMD and extjs. In my Main.js i have something like
Ext.define('Abc.view.main.Main', {
extend: 'Ext.panel.Panel',
xtype: 'app-main',
header:{
height: 25,
titleAlign: 'center',
title: 'new tile,
padding: '0 0 0 10'
},
requires: [
'Abc.view.main.MainController',
'Abc.view.main.Component'
],
If you see requires, i am requiring some classes. If i remove all the classes in requires and leave it like
requires: []
all the pages are loaded properly only. So whats the benefit i am getting by adding files in requires.

First, your application (Application.js) has a list of required views and stores and controllers. If your controller and component are in these "global" lists, they are already loaded when your requires list is evaluated, so you don't see a difference at all. If you reuse the component in other projects, and you forget to add it to the Application.js, you may see a difference.
If they are not already loaded when they are needed, three things can happen:
The xtype is not yet registered with ComponentManager, so if you instantiate by xtype, this will fail ("could not resolve dependency").
If you instantiate by full name, you may get the warning that the components are loaded synchronously, which is slower than the asynchronous loading of the whole requires list at once.
If you instantiate using variables, Sencha Cmd is completely unable to add the required files to the dependency tree, and they may be missing in the built file. Example:
var doWindow = true;
var component = doWindow?'Ext.Window':'Ext.panel.Panel';
Ext.create(component,{
...
});
Because the requires list is also used by Sencha Cmd to resolve the dependency tree and make a correct partial order of the component definitions in the built js file.

Related

EXTJS how to access global variables in store

I'm quite new to Extjs, I'm needing to pass some data to my stores, I mean, I need to fetch some URL from a singleton configuration file, but reading in the Official documentation I am not able to find a require method in the store. So, I wonder how to tell my store to fetch that URL from a configuration file?
I am not sure which version of Extjs you are using. The answer is based on Extjs6 which I am using. We add the singleton (mostly common configs) files in the application(Application.js) level so that the file will be available across the entire app.
For example,
singleton file is 'Some.Globals.configs'
//Application.js
Ext.define('Some.Application', {
extend: 'Ext.app.Application',
requires: [
'Some.Globals.configs'
]
});
Then anywhere in the application, you can access directly as mentioned below.
Some.Globals.configs.respectiveConfig
If you are extending Ext.data.Store you should be able to use requires property
eg.
Ext.define('My.awesome.Store', {
extend: 'Ext.data.Store',
requires: [
'My.global.Config'
]
...
});

Sencha - Conditionally adding namesapce in requires

I have a requirement that I want to add namespaces in requires conditionally.
e.g. In below example I want to add 'views.popupgrid' name space on specific condition. Currently it's always loaded.
requires: ['Ext.window.MessageBox','views.popupgrid','user.MyUser' ]
Conditional dependencies are not supported by the Sencha toolchain. While you would be able to write in a text editor of your choice
requires:[
(location.hash=='#test')?'testpopup':'normalpopup'
]
and this would work in the uncompiled version, Sencha Cmd would not be able to compile it correctly, and would throw errors.
Therefore, Sencha Architect does not support this syntax.
What you can do, while staying Standards-compliant: you can use Ext.Loader.loadScript, e.g. like this:
Ext.define('MyForm',{
extend: 'Ext.form.Panel'
initComponent:function() {
var me = this;
me.callParent(arguments);
if(x==3) Ext.Loader.loadScript({
url:'MyCustomFormComponent.js',
onLoad:function(){
me.add({
xtype:'mycustomformcomponent'
});
})
});
}
})
Please note that in this case you will always have to deliver MyCustomFormComponent.js alongside the minified app.js, because the dependency cannot be resolved by the toolchain. Also, depending on the connection, there may be a visible delay before the resource is loaded and the component is added to the form.
It is usually faster and smoother to always load the dependency, especially if you intend to deliver the app as a single minified javascript file (e.g. using Sencha Cmd).

ExtJs - how can I find a specific config from code in the docs

Just started to take my first steps with ExtJs, however I cannot figure out this one, although it must be totally obvious. In the code below, the legend has a config called "docked", how can I find it in the docs?
I searched multiple ExtJs docs versions for it but I cannot find it.
What I do:
I see that we create an object of the class Ext.chart.PolarChart. So I go to the docs for this class.
There I see a config called "legend" of type Ext.chart.Legend. Then I go to the docs for this class. But there is no config called "docked".
I assume that ExtJs docs show also inherited configs. I also looked for some more specific Legend class, thinking that the one listed in the docs is a parent class of other legend classes, but I could not find any other matching classes. For sure I am missing some JS or ExtJs concept, I just can't figure it out.
What is the correct way to figure out where the legend config "docked" comes from/is defined?
var donut = Ext.create('Ext.chart.PolarChart', {
title: 'Test',
animation: true,
width: 300,
height: 300,
renderTo: Ext.getBody(),
store: storeA,
legend: {
docked: 'bottom'
},
series: [{
type: 'pie',
angleField: 'value',
colors: ["#9aff4f", "#35b4e3", "#ffb400"],
donut: 20,
label: {
field: 'name',
display: 'inside'
},
highlight: true
}]
});
I think you did nothing wrong. You're entirely correct to search for "docked" in Ext.chart.Legend, and doing this for other configs should result in a hit with high probability.
But there are two things:
Other programmers can always put configs into their component definitions that are wrong and do nothing. It could be that they wanted to write dock: "bottom", did it wrong, but for some reason didn't see their error in the results, because the legend does what it should. You should definitely try what happens when you comment away that line. Does the legend change? (This is easy with docked, which should directly affect layout, but could be less easy with more obscure configs)
Not all possible config properties are public, and therefor documented. legend has a hierarchy and mixins, so if that config shows any effect, you will have to manually check the code of all components in the hierarchy and all mixins whether any of the components looks into a docked property.
Components are javascript objects, they allow for so-called expansion: if you add a config that is not processed, you can reasonably expect that the component has that property afterwards, which can then be processed from inside your code (outside of the component itself). For reasonably big code, you should start to put all such expansions into custom components, and use jsducks to generate a HTML documentation on these custom classes with their custom configs.

Ext.require is required

I start my app in extjs 4, using a
Ext.Loader.setConfig({enabled: true});
but when using my custom controls, I always need to explicit require this controls:
Ext.require('App.controls.CoCheckbox');
Ext.define('App.view.atendimento.FormAgenda', {
extend: 'App.controls.CoForm',
...
My control:
Ext.define('App.controls.CoCheckbox',{
extend: 'Ext.form.field.Checkbox',
alias: 'widget.cocheckbox',
inputValue: true
});
Why I need to explicit declare those requirements?
In Extjs you organize your code in files then, your App.view.atendimento.FormAgenda is in one file and your App.controls.CoCheckbox is in another file. I assume App.view.atendimento.FormAgenda uses at least one instance of App.controls.CoCheckbox so, when extjs needs to create an App.view.atendimento.FormAgenda instance, it requires to download the file where App.controls.CoCheckbox is defined.
Basically, extjs has no other way to know the component dependencies. You have explicit them.

Ext JS: what is xtype good for?

I see there are lot's of examples in Ext JS where instead of actually creating Ext JS objects, an object literal with an xtype property is passed in.
What is this good for? Where is the performance gain (if that's the reason) if the object is going to be created anyway?
xtype is a shorthand way to identify particular components: panel = Ext.Panel, textfield = Ext.form.TextField, etc. When you create a page or a form, you may use these xtypes rather than instantiate objects. For example,
items: [{
xtype: 'textfield',
autoWidth: true,
fieldLabel: 'something'
}]
Moreover, creating pages in this manner allows Ext JS to render lazily the page. This is where you see a "performance gain." Instead of creating a large number of components when the app loads, Ext JS renders components when the user needs to see them. Not a big deal if you have one page, but if you exploit tabs or an accordion, many pages are initially hidden and therefore the app will load more quickly.
Furthermore, you may create and register new components creating xtypes of your choosing. Ext JS will similarly render your components lazily.
You may also retrieve components by ID. Since your component (as well as the Ext JS components) may provide a bunch of nice behavior, it is sometimes convenient to search for and retrieve a component rather than a simple DOM element or node.
In short, xtypes identify components and components are a key aspect of Ext JS.
I'm new to Sencha/Ext JS but I think at this point the odd notion of having a shorthand definition identifier string for only UI components must be to satisfy legacy users.
Look at the "List of xtypes" here: http://docs.sencha.com/touch/2-0/#!/guide/components
Is there any good reason to use a similar-but-not-quite-the-same string identifier as the "class" name as the shorthand definition identifier? I don't think so.
Check the following sample of some xtype to class name mappings for Sencha touch:
video - Ext.Video Ok this sort of makes sense - lowercase version of 'class' name
carousel - Ext.carousel.Carousel Same pattern here
carouselindicator - Ext.carousel.Indicator Um, ok - we'll include a package too
navigationview - Ext.navigation.View And again here
datepicker - Ext.picker.Date Ok, wtf?
Some of the arguments above for xtype were that it allowed deferred instantiation of components. I think that is completely irrelevant - what allows deferred instantiation is the fact that Sencha/Ext JS supports the specification of a string identifier in place of an instantiated component in a view hierarchy.
The mapping of a particular string to a particular component that might be instantiated later is completely arbitrary - and in the case of Sencha/Ext JS, unfortunately silly (see examples above).
At least just follow a sensible pattern - for example why couldn't a Ext.Label have an "xtype" of Label? Too simple?
In reality I know why - it's because they made xtype names that read well - there are many repeated class names that wouldn't work (Ext.Panel and Ext.tab.Panel), and pickerDate would just sound stupid.
But I still don't like it - it's an odd little inconsistent shortcut that obfuscates more than it helps.
I asked the same question as Joe, but I found the answer. If you use xtype, one approach is to also specify an itemId in the same object:
{
itemId: 'myObject',
xtype: 'myClass'
...
}
Then you can find it with getComponent() as in
this.getComponent('myObject');
If you declare a class and give it an xtype, you can query it later with Ext.ComponentQuery.query()
For example:
Ext.create('MyApp.view.MyButton', {
xtype: 'mybutton',
.....
});
Later in your code, if you do:
var buttonArray = Ext.ComponentQuery.query('mybutton');
then buttonArray will contain an array of components of that class type. If you create components inline, your component query will be more complex.
Another advantage of xtypes is that if you move your classes around (let's say, you add another subdirectory under "view": MyApp.view.button.MyButton), then your component queries can still remain the same, since your xtype doesn't change. Once your project gets large, you will start creating subdirectories and moving classes around.
An xtype is simply a name given to represent a class. It is a
definition object which don't need to be instantiated when used in
any part of application.
While registering a xtype, we simply use this syntax: Ext.reg(<xtype name>,<classname>). But, we don't use the new keyword with the class name because the Component Mgr will automatically create instance of this class only if needed eg. in response to an event like click.
We don't need to get an instance manually because after registering an xtype, the 'Component Mgr' will automatically create an instance for the class represtented by that xtype only if it is used anywhere in the application or it simply don't instantiate that class if not used elsewhere. Component Mgr runs this code:
create : function(config, defaultType){
return new types[config.xtype || defaultType](config);
}
xtype don't instantiate the class when Ext.Ready runs. But, new Ext.Container() will create all instances when Ext.Ready runs. So, using xtype is intelligent for large applications to get rid of garbage objects.

Resources