Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExtJS: What's the point of requires?

Tags:

I've been trying to figure out what requires does in Ext JS 4, and I can't seem to come up with a reasonable answer. Let's say I have the following code:

app.js

Ext.Loader.setConfig({
  enabled: true
});

Ext.Loader.setPath('Ext.ux', 'examples/ux');

Ext.application({
  name: 'Test',
  appFolder: 'app',
  controllers: ['TheController'],
  requires: ['Test.Utils', 'Test.Utils2'],  // I don't think this does anything... couldn't find this option for Ext.application
  launch: function() {
    Ext.create('Ext.Viewport', {
      layout: 'border',
      items: [{
        xtype: 'thegrid',
        region: 'center',
        title: 'blah!'
      }]
    });
  }
});

app/controller/TheController.js

Ext.define('Test.controller.TheController', {
  extend: 'Ext.app.Controller',
  models: ['TheModel'],
  stores: ['TheStore'],
  views: ['TheGrid'],
  init: function() {
  }
});

app/view/TheGrid.js

Ext.define('Test.view.TheGrid', {
  extend: 'Ext.grid.Panel',
  alias: 'widget.thegrid',
  requires: ['Test.store.TheStore'],
  store: 'TheStore',
  columns: [
    {header: 'Name', dataIndex: 'name'},
    {header: 'Phone', dataIndex: 'phone'},
    {header: 'Hello', dataIndex: 'hello'}
  ]
});

app/store/TheStore.js

Ext.define('Test.store.TheStore', {
  extend: 'Ext.data.Store',
  requires: ['Test.model.TheModel', 'Test.Utils'],
  model: 'Test.model.TheModel',
  data: [
    {name: 'keanu reeves', phone: '1800matrices', hello: Test.Utils.getText()},
    {name: 'james earl jones', phone: '1800starwar', hello: 'nothing here'},
    {name: 'barack obama', phone: '1800prsidnt', hello: 'hello world'}
  ]
});

app/model/TheModel.js

Ext.define('Test.model.TheModel', {
  extend: 'Ext.data.Model',
  fields: [
    {name: 'name', type: 'string'},
    {name: 'phone', type: 'string'},
    {name: 'hello', type: 'string'}
  ]
});

app/Utils.js

Ext.define('Test.Utils', {
  singleton: true,
  requires: ['Test.Utils2'],
  getText: function() {
    return Test.Utils2.hello + 'world';
  }
});

app/Utils2.js

Ext.define('Test.Utils2', {
  singleton: true,
  hello: 'hello'
});

I realize this is a really long example, but I needed to make sure I fully portrayed what I was doing. Utils relies on Utils2 because it needs to call Utils2's hello variable. The rest of the code is setting up a grid and calling the Utils.getText function in TheStore. Firebug throws a Test.Utils is undefined on line 6 in TheStore.js, and at that point in time, Test.Utils obviously doesn't exist, but Test.Utils2 does.

My question is... why does Utils2 exist, but Utils doesn't? I thought requires brought in the classes that I needed, thus allowing me to use them, but I guess I'm wrong. I've read the Sencha docs and a multitude of threads, but nothing really made sense, and it doesn't really explain this example. Can anyone shed some insight here? I'd appreciate it.

**Also, I realize I'm doing some dumb things here, but it's merely for an example, so I'm not looking to combine the global Utils or not use globals at all... I'm just trying to figure out the requires option.

UPDATE

Thanks to Izhaki's answer below, I figured something out. If I want to use a required class in a class I'm defining, I would have to wait for the object to get created (IE, use initComponent), so my store and grid code changes to:

app/store/TheStore.js

Ext.define('Test.store.TheStore', {
  extend: 'Ext.data.Store',
  requires: ['Test.model.TheModel'],
  model: 'Test.model.TheModel'
});

app/view/TheGrid.js

Ext.define('Test.view.TheGrid', {
  extend: 'Ext.grid.Panel',
  alias: 'widget.thegrid',
  requires: ['Test.store.TheStore'],
  store: 'TheStore',
  columns: [
    {header: 'Name', dataIndex: 'name'},
    {header: 'Phone', dataIndex: 'phone'},
    {header: 'Hello', dataIndex: 'hello'}
  ],
  // This is the change that works
  initComponent: function() {
    this.callParent();
    this.store.loadData([
      {name: 'keanu reeves', phone: '1800matrices', hello: Test.Utils.getText()},
      {name: 'james earl jones', phone: '1800starwar', hello: 'nothing here'},
      {name: 'barack obama', phone: '1800prsidnt', hello: 'hello world'}
    ]);
  }
});

This works, but my last question is... do I have to have the requires for TheModel in TheStore, and/or TheStore in TheGrid? It seems like TheController is taking care of all of those requires because I can use Test.Utils in TheGrid, but TheGrid doesn't specifically state that it requires Test.Utils.

Also, this example from the Sencha docs makes me more confused because I'm clearly not using Test.Utils until TheStore is created, but this example seems like it can use the Child class without having to wait for it to initialize (using initComponent).

like image 842
incutonez Avatar asked Jun 12 '12 01:06

incutonez


People also ask

What is requires Ext JS?

Requires - All classes required to be defined for the class to be instantiated. Uses - A list of classes potentially used by the class at some point in its lifecycle, but not necessarily requried for the class to initially be instantiated. Subclasses - Classes that extend the current class.

What are the advantages of using Ext JS?

It allows you to save time on development and make the process easier, there are no compatibility issues, many multiplatform advantages, and you get great support services from Sencha.

Is Ext JS popular?

Ext JS is used by less than 0.1% of all the websites whose JavaScript library we know.

Is Ext JS single page application?

Ext JS by Sencha is becoming the ExtJS is a rich, compelling and intuitive open source framework best suited for building single page applications. It offers very rich set of UI components and thus giving a tough competition to other JavaScript frameworks like AngularJS or ReactJS.


1 Answers

This is actually not a dumb question at all.

You can look at requires as a way to tell ExtJS:

"When you construct an object of this class, please make sure to dynamically load the required scripts first".

You are right about this line:

requires: ['Test.Utils', 'Test.Utils2'],

not being needed in app.js, reason being is that the application already has:

controllers: ['TheController'],

which is the same as saying you require the js script in which TheController resides (any model/view/controller/store definition also mean that the related scripts are required, ie will be dynamically loaded).

TheController has:

requires: ['Test.model.TheModel', 'Test.Utils'],

which will load these dynamically - this is why the same requires is not needed it app.js;

The reason you get Firebug throwing Test.Utils is undefined is that you give a config (hello) with a reference to an object that is not yet dynamically loaded - there's no Test.Utils in the scope until TheStore is constructed.

like image 119
Izhaki Avatar answered Oct 12 '22 23:10

Izhaki