Skip to content

Components

Azarattum edited this page Nov 23, 2020 · 11 revisions

Concept

Components are basic building blocks of your application.

There are 4 abstract types of component in TheFramework:

You write your own components as derivatives of these abstract component types. You will extremely unlikely need to write your own abstract type, but nothing stops you from doing so.

Unlike in the most frameworks a UI element is not necessarily one component. There is a clear differentiation between logic components (Controllers) and template components (Views). You can build several layouts that run on one logic or lots of different implementations working on one layout. Of course you can go with the traditional way (1 controller = 1 template) too.

Types

Model is the most simple type of an abstract component. It does not have any special logic of binding built into it. Essentially it is just a JavaScript class with a default export. That simplicity makes it extremely powerful and flexible because you can make whatever you need of it. Usually you want to model some kind of user independent logic in it. So, it should not depend on UI or user input, should not reflect any state outside or have any side effects. This is the only type of components which should be used directly within other components.

Controller defines the behavior of your application. Your logic or interaction with UI elements should be implemented here. In browser controllers have a direct access to their containers and elements within them, also they are able to be data-binded to the UI. However, controllers also can be independent from a specific container and exist in a singleton manner. Something like a router would be a perfect example as it has to handle user interactions but is not necessarily dependent on anything on the page.

Service is a special kind of component. It's main purpose is doing heavy computation stuff. Services behave similar to controllers, except for UI access. They cannot have it by design because every service runs in a separate thread (in Worker). Thanks to comlink and some custom wrapper loaders, interaction with services in TheFramework made seamless and should not be much different from dealing with something like Controllers. However the fact of a different thread should always be in mind while working with services.

View is an exclusive to browser type of component. It defines the layout and style of a page. Views typically do not contain any JavaScript except for the initialization step. Views are used to organize and manage your layout. Every view defines a custom element that can be used across your document. They have access to data passed into them, so they can render accordingly. Finally, views have all the benefits of preprocessing from Pug and SASS.

Relation

Relation is a static component's property that is either null or object[]. It defines how many instances of the component will be created. When relation is null component can only have a single instance at a time. When an array is specified for each of its elements will be created a component object with the element as a relation. If the array changes, components will be updated appropriately on Application.refresh().

Default relations for the component types are:

Under The Hood

Components themselves have a fairly simple interface defined in src\components\common\component.interface.ts. They can be created, initialized and closed. Component type should return relations array for application to decide how many instances of a component it needs to create. Each relation passed to the instance of a component upon creation. Besides, an Exposer instance (object that defines behavior of sharing component's logic with the global scope) and a refresh callback (used to notify application that components might need an update. For example, when page renders a new content) are passed into a newly created component.

After creation, handlers that were defined in your app are applied to the instances. At this step usually all the event listeners are registered.

Finally, the components are initialized. This process consists of some predefined type-specific logic and the one that you wrote in component's initialize function. To that function all the configurations for this component type are passed as arguments.

Components Initialization Sequence