⬆️ ⬇️

Client application architecture on ExtJS. Part 1

Extjs

The most difficult thing in any job is to start it. So, where to start our huge client application? In this part, I will tell you where to start and cover three topics: How to organize code, What is a facade, how to build it, what are components (and, of course, how to start writing).



It should immediately warn that the article is designed for developers who have already used this library in their projects. The article is not for beginners, as there is a lot of trivial code missing.



Start



I would suggest creating a hierarchy of directories in your javascript folder. Suppose this folder is called js. Then the directory hierarchy I recommend is as follows:



The ext folder contains the framework itself, and the js files are external to the framework. The / js file will store the only file that will be the front of our application. In / js / components there will be all your component heirs, which we will talk about in detail later, in / js / plugins there will be plug-ins, i.e. components included in the plugins collection of some other components. I also will tell about plug-ins a bit later. And finally, / js / resources in which you can store resource files with static variables, various helper functions, object overrides, etc. and so forth

')

Next, on our page with the application (say, index.html), we organize our scripts in the header in the following way:

  1. / ext files
  2. resources from / js / resources
  3. plugins from / js / plugins
  4. component modules from / js / components
  5. facade from / js


Why exactly in this order? Because such is our hierarchy of dependencies. The framework does not depend on our scripts and is worth it first. Resources can depend only on objects and functions from the framework, plug-ins use resources and frameworks, modules-components use plug-ins, resources and frameworks, and the facade uses everything higher than it. That's what he facade.



Thus, we solved the problem of dependency, which I got up several times due to the incorrect location of the components.



Dependency management in javascript is generally a separate topic, but if you're interested, I advise you to pay attention to Jingo . I got acquainted with this library quite recently and, as it seemed to me, using it too much would have to be changed in the existing, already debugged code. But the problem of dependencies this library solves very elegantly.



Facade





Next is to write the frame of the facade. What he really is? And he is a normal function, which is eventually mounted to Ext.onReady (that is, the facade begins to "live" after the house-model of our index page is built). Here is an example of the facade:



Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  1. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  2. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  3. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  4. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  5. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  6. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  7. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  8. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  9. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  10. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  11. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  12. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  13. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  14. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );
  15. Copy Source | Copy HTML /** <br/> * filename: facade.js <br/> * description: Application Layout <br/> */ Ext. namespace ( "Layout" ); Layout. base = function (){ // Ext.QuickTips.init(); // , // Viewport // ... return { init: function (){ new Ext.Viewport({ /* , */ }); } }; }(); Ext.onReady(Layout. base .init, Layout. base );




Components





In Viewport, in the facade we connected our panels and navigation. Now it's time to adjust the basic interaction of the menu items with the content area in Viewport. Suppose your goal is to change the content by clicking on the menu items. You have the “Reports” element and the “Settings” element in your menu and you want to see in the content area, when you click on these menu items, respectively, the content corresponding to the reports and the content corresponding to the settings. To do this, you place a report component or a settings component in the items collection in the content panel (the situation may vary slightly depending on which layout you applied in the content area).



So. In this article I will adhere to the agreement that the components are the heirs of the visual components in Ext. You almost always need to have at least redefined standard visual components. In various Ext tutorials, such components are called preconfigured controls and represent the implementation of the concept of inheritance in OOP.



So, briefly, overrides are implemented using the example of GridPanel, which acts as a base class:

Copy Source | Copy HTML
  1. Ext. namespace ( "Application.Reports" );
  2. Application.Reports.BaseReport = Ext.extend (Ext.grid.GridPanel, {
  3. constructor: function (config) {
  4. // We rarely have to use the constructor itself, so this method can be done
  5. // omit if we don’t want to do something with the configuration before it hits
  6. // into the base constructor. But to have an idea that the constructor function is still there - it is necessary.
  7. // We must not forget to call the base method, if there is one
  8. Application.Reports.BaseReport.superclass.constructor.apply ( this , arguments);
  9. }
  10. , initComponent: function () {
  11. // But this method is very important. Component initialization is called after the constructor.
  12. // Therefore, the redefined configuration is more priority than the configuration specified by the user
  13. // in the constructor. In it we will redefine the configuration of the object.
  14. // Copy with replacement all properties of the second argument to the first. What would the user be there
  15. // in the constructor for the properties, neither determined if these properties are in the second argument — they
  16. // replace the properties in our object
  17. Ext.apply ( this , {
  18. title: "Our Title"
  19. , loadMask: true
  20. / * Other properties * /
  21. , plugins: [
  22. // Never mind what Ext.ux.grid.MetaGrid is.
  23. // RESOURCES.SETTINGS.RECORDS_PER_PAGE is the singleton defined in the resource file in / js / resources
  24. // RECORDS_PER_PAGE = value 50.
  25. new Ext.ux.grid.MetaGrid ({paging: {perPage: RESOURCES.SETTINGS.RECORDS_PER_PAGE}})
  26. ]
  27. });
  28. // Do not forget to call the base initialization method
  29. Application.Reports.BaseReport.superclass.initComponent.apply ( this , arguments);
  30. }
  31. });




On this I finish. In the next part :

Source: https://habr.com/ru/post/75705/



All Articles