Application Architecture
To understand how Angular2+ applications work, we refer to the official documentation of Application Architecture by an Angular team.
Modules
The application is divided into four fundamental types of modules. Each has specific sets of tasks. They interact with one another by modular declaration or services. Root module (AppModule) controls all of them either by dependency injection or lazy loading. Root module includes structural dependencies to build the entire Angular 2+ application.
All the modules will include their own view controllers and providers which can be used to display the main component. The supporting components will be defined under support directory of a particular module. If any supporting component can be used in more than one module for the same purpose, it shall be defined in shared modules.
1. App Module (root)
It is the top most module in Angular2 hierarchy. All the external dependencies that require API keys to initialize are declared in this module. The modules, components, services and directives imported/declared in this modules can be in use for the entire lifecycle of the application. It is advisable to divide the application structure into different modules so that one single module is not overloaded. External dependencies and modules are initialized and set up in root module. The initialization process involves setting them up with application’s root configurations and/or providing API keys if needed. There are several components that are loaded in the main page and remain the part of life cycle throughout the application (such as Sidebar). Such components and their services are loaded from the root module to keep them in the loop throughout the life cycle. Here, given below is the list of such components and their purpose:
Component
Purpose
Sidenav
The navigation bar which toggles at the left side of the screen. Corresponding Service: SidenavService.
Angular services act as singleton classes. Once they are loaded, they remain in the context of the entire lifecycle of the module. They are used to communicate among different components or external resources (such as WebSocket or API server). Services defined in the root modules are generally used for transferring data to-from global components. These services can also be used for external communication when data is required globally or by most of the components. Here, given below is the list of such services and their purpose:
Service
Purpose
Toolbar
Mostly used for changing content in toolbar UI.
Sidenav
Mostly used for changing UI behavior of Sidenav bar.
One of the most significant parts of single page application is routing. Oizom application uses built-in routing module provided by the Angular team. Considering the future aspects of the application, we have considered to develop it in a way that no extra module is loaded at a time. The concept is called lazy loading. Angular 2 provides built-in support for lazy loading by writing minor configurations in routes. The modules which are not lazy loaded are directly imported into root module. Pointer/path of the lazy-loaded modules are provided in router modules so that when the application is redirected to that path, corresponding modules are loaded from the accurate path on requirement basis. After adding all the dependencies and in-app components/services and other supporting files to application’s root module, the root UI component where the entire application is to be loaded is bootstrapped.
2. External Modules
The development team develops the modules to make it more suitable for Oizom’s development environment. But the team considered to use several third party libraries to speed up the development process. We can divide the external modules into two categories: Typescript modules, and Javascript Modules. Typescript modules include Google Maps and Angular Material. They are natively built in typescript, especially for Angular 2 framework. No extra components or modules were required to use these libraries. Since typescript is derived from javascript, all the javascript libraries are by-default supported by typescript. But typescript follows different sets of rules, so separate declaration and initialization of extra components/services/directives is needed to make the code more usable and avoid basic initializations. Javascript modules include moment, socket.io, progressbar.js.
Module
Purpose
This framework implements material design concept in angular 2 application. The framework itself is in beta right now, so you may experience some bugs in the built-in components provided by Angular Material. For extensive personalized experience, in-app style designs are more preferable.
This library to parse, validate, manipulate, and display dates in JavaScript.
A javascript library (client) to communicate data real time.
An UI library to display progress bars. All the progress bars displaying gas levels and the AQI meter on the overview component are designed using this library. The library is not used directly as mentioned in its docset. To use this library, you need to write a new component in support directory of the module and extend shared/shapes/base-shape.component. Make changes to core UI element only when it is necessary.
Library for data visualization. You must follow the standards provided in shared/charts/
A modern JavaScript utility library delivering modularity, performance & extras.
Simple wrapper for cross-browser usage of the JavaScript Fullscreen API. It's used in display and plugin module.
directive for Coping Clipboard
plugin for Download file
3. Content Modules
All the modules which interact with the user are content modules. These modules include computational logic about how the data will be populated, how that data will be displayed, how the user can manipulate the data, improvement logic based on analysis on user experience, and behavior of the UI design.
Nine modules are currently under development right now:
Module
Purpose
Overview
Dashboard
Report
Analytics
Profile
Alerts
This module details user's alert notifications and custom configurations. A user gets a notification on the reaching the limit of particular gas so he can more analyze environmental changes.
Display
This module consists of displaying various screen frames in full-screen mode.
Heatmap
This module consists of visualization of various layers (like AQI, PM2.5, PM10 and so on...) A user also can compare two places air quality.
Plugin
This module consists of various screen frames for embedding ad places.
4. Shared Modules
All the content modules are sandboxed so that they can be loaded on demand rather than loading them all at once and establish complex interdependency. Some modules are developed in such a way that it can be used by other content modules to share the data or view components. It minimizes interdependency graph and increases the probability of the module being lazy loaded when needed and not affect the other modules. Common style sheets and constants json are also considered to be added in shared modules.
Here is the list of Shared Modules used in web applications:
Module
Purpose
Charts
Shapes
Sidenav
UI component for navigating to different routes in the application. There is a specific format to store menu details for Sidenav menu. The module is shared with every parent sub-modules that are called directly from the Sidenav. The parent submodules need to call a service subroutine to notify about the currently active module so that Sidenav is updated to notify a user.
Toolbar
UI component to display the title and crucial details about the currently active module. The component only keeps track of title as for now. The currently active component needs to call a service subroutine to request changes in toolbar title.
AppConstants
It includes global constants used in the application. Such as keys for storing values in local storage or URL and their parameters for API calls.
Theming
It defines design standards for the applications.
Guards
It defined for various routing options
Animations
It defines for various types of animation used in the application.
Date picker
It used as date-picker in the application.
pipes
It used to handle various type of data in HTML.
screens
It defines various screens for full-screen mode.
Other Important Details of Application
1. Routing
An oizom application uses built-in routing module provided by the Angular team. Considering the future aspects of the application, we have considered to develop it in a way that no extra module is loaded at a time. The concept is called lazy loading. Angular 2 provides built-in support for lazy loading by writing minor configurations in routes. The modules which are not lazy loaded are directly imported into root module. Pointer/path of the lazy-loaded modules are provided in router modules so that when the application is redirected to that path, corresponding modules are loaded from the accurate path on requirement basis.
For better navigation experience, the route data/parameters can help making the initialization dynamic from URL in any component. The route data can help assign appropriate values for child component in other components in the viewport. They can also help identify the specific settings of a parent component for a child. The route parameters can help getting data from URL itself. It can be used for displaying appropriate data by providing the appropriate route. There will not be any need to configure data from app to reach any particular stage where it can also be done with providing the proper route. Another way of passing parameters from the route is using query parameters. If multiple parameters are desired to pass, using device parameters will block a lot more children routes. In that case, query parameter can be of use. You can pass multiple parameters with "?" and "&" identifiers. Using appropriate navigation technique will lead to make the application more dynamic and URL specific.
2. Style sheets
An oizom application uses an extended version of Cascading Style Sheets, SCSS (https://sass-lang.com/). It allows you to use variables, nested rules, mixins, inline imports, and more, all with a fully CSS-compatible syntax. Here at Oizom, we follow several style standards. With SCSS, we can generalize the standards and use it for later usages. There are certain cases, such as, overriding sever design standards which are strictly followed by Angular Material or any other design framework that can not be changed easily from SCSS. In such cases, main style.css
is defined and imported in index file at HTML source only to forcefully effectuate the changes. All the views have their separate controllers as well as style sheets (scss).
3. Supporting Elements
Every module consists of the components (view controllers/providers) which serve the purpose of dealing with the main content of the module. But some components use some external library or require an internal initialization in order to optimize the coding complexity. These components are not shared among other modules, but they may be shared among the parent and child components in a module. These components are categorized for support mechanism and stored in a separate directory in a module (named "support"). Depending on the functionality, these support components are defined in the content module or root module (exceptional cases where initialization in the content module doesn't support the mechanism. e.g. dialog box in AngularMaterial)
4. Assets
The application ("app") directory includes on typescript and web design (HTML/SCSS/CSS) code. Any other kind of resource which is required for application is stored in "assets" directory. The directory holds mostly the media files and the addition fonts used in different components. The hierarchy of the subdirectories must be maintained by the type of the file or the purpose of the file whichever servers the best purpose for that particular file or set of files. All the additional files which are used for testing or temporary purposes shall be stored in the assets directory itself.
5. Source Version Control
The development team at Oizom uses git protocol for version control and github for maintaining code repository. All the files in the application directory must contain the version number they were created in and they were last modified in (use @since and @version). Do not commit sensitive data on the repository unless approved by Sohil OR Mrugesh OR Nayan. Keep the sensitive data in gitignore or change it to values used for localhost and then commit to git. List unnecessary, heavy files or dev-dependencies under .gitignore to avoid uploading the large chunk of files to the cloud. Consult development team for the further guidelines on version control.
Last updated