Component-based application architecture with AngularJS and Typescript
- Before creating a component you have to decide if it will be a Presentational component or a Container component .
- The child component communicates any update on the data through its output bindings ( & ).
- Presentational components can contain both container components and presentational components and vice versa
- The parent component can pass a method to this binding which the child component can call back and optionally send back any data to.
- The container component eventually decides what action to take with the data, not the child component.
Ordina JWorks Tech blog
@ryandegruyter: Structure your app with a component-based architecture in @AngularJS and @Typescript @lifeatordinabe
In this article I will offer some basic guidelines on how to create a scalable AngularJS application with reusable, well encapsulated components that are easy to maintain and refactor. AngularJS (version 1.5.5 at the time of writing) and its latest features offers us the ability to structure our apps as a tree of components.
It can even have its own (relative) routing configured if you take advantage of the new Component Router.
If you are on a team with multiple front-end developers you can easily divide the work by letting each developer focus on a separate component. It also helps in migrating to Angular 2, though I cannot promise it will be an easy task. Another bonus point is you are getting into the mindset of modern front-end development: web components.
My preferred toolchain when developing AngularJS applications consists of Typescript, NPM and Webpack. The sample code in this article and the sample application are created together with these tools.
You can find the sample application on Github: https://github.com/ryandegruyter/angularjs-components
What is a component?
True web components can isolate their structure, appearance and behavior. They make use of a technology called the Shadow DOM, which isolates the component in a separate DOM tree. This element will have its styles and scripts encapsulated, they will not conflict with the styles and scripts inside the parent DOM.
Angular 2 takes full advantage of this technology, but unfortunately AngularJS, the framework I will be talking about in this article, does not.
Lucky for us we are able to mimic the effect of Web components by using directives. We can write a reusable UI element, declare it with a custom tag and configure it by supplying attributes on the element. My advice is to be sure to use correct naming conventions and a module system so styles and scripts will not conflict with each other.
To create and register a custom element in AngularJS, we can use either methods:
While components are restricted to custom elements, directives can be used to create both elements as well as custom attributes.
There are 3 types of directives:
method is a helper method which creates a directive set with default properties.
When do we use .directive(), and when do we use .component()?
helper method because it:
Beginning with a component-based application architecture we need to have a root component. Before creating a component you have to decide if it will be a Presentational component or a Container component.
binding) with their direct parent.
These components are unaware of any application state, and they only get data passed down to them.
A simple presentational root component.
– and zero outputs. It doesn’t call a service or fetch any data. It doesn’t update any outside resources or make any requests to manipulate application state. Also notice how easy it was to register this component directive.
method when creating custom UI elements.
). The container component eventually decides what action to take with the data, not the child component.
Let’s look at an example of a container component, I will leave out the complete template for brevity’s sake, you can view the complete code in the companion repository.
First we start with our component definition:
). Our container component can bind a callback method on the on-selected attribute which offers an opportunity for the currencies-select component to communicate with its parent component.
Below we define our components controller, here we can set and manipulate our template’s view model.
equal to a list of currencies fetched from the data service.
So how does our presentational component definition look like?
. We can guess that it’s a flag for showing the selected currency. But as a new developer, we cannot be sure.
As you can see this component does not inject any data services or manage any outside state. It only receives data through its input bindings:
method gets called, it passes the selected currency which gets communicated back to the parent component.
And inside the parent component’s template:
is not descriptive.
To access the selectedCurrency you would use the property on the $locals object with the same name:
In our previous example we saw an example of child to parent communication by mapping an output binding:
The parent component can pass a method to this binding which the child component can call back and optionally send back any data to.
A child component can also require its parent components controller by mapping it in the require property:
Be aware that this creates a tight coupling between the child and parent component.
We should access and manipulate application state in our container components, but only through services, a component’s controller primary responsibility is to manage the template’s view model. You can implement a custom observer pattern inside the service, or use the rootscope as an eventbus.
A component controller can get notified by any changes by subscribing to the service: