Assistant Engineer
Assistant Engineer
  • UID622
  • Fans1
  • Follows0
  • Posts52

[Share]Angular 2: Experience learnt from AngularJS 1.x

More Posted time:Oct 27, 2016 9:50 AM
Editor’s note: The final version of Angular 2 has been officially launched and the all-platform successor of Angular 1 has been born. The defects in version 1.x make it not worthwhile to be integrated with powerful tools. Let’s take a glimpse at what annoying problems in 1.x versions have been solved in Angular 2.

AngularJS 1.x follows the micro-architecture model of Model View Controller (MVC). Someone may argue that it looks more like Model View View Model (MVVM), because the controller has its own independent syntax, and the view data model exists as the scope or the attribute of the current context. But we can achieve the same purpose with Model View Presenter (MVP). Because the application logic can be organized in various forms, the core team calls the AngularJS 1.x as a Model View Whatever (MVW) framework.
In any AngularJS application, the View should be from command sets. Various commands work together to constitute the user interface with complete functions. The service is responsible for encapsulating the business logic of applications. In the service code, we can communicate through HTTP and RESTful services, and communicate in real time using WebSocket or even WebRTC. For our applications, the service is a fundamental component to realize the domain model and business rules. Controller is another component and is mainly responsible for processing user input and forwarding the execution process to corresponding services.
Although the service and command have explicit rule definitions, in iOS applications, we can often see the anti-pattern of Massive View Controller. Sometimes, developers will try to access or directly modify the DOM in the controller. At the beginning, such a method was used to realize some simple functions, such as modifying the tag size, or rapidly modifying the tag styles. Another anti-pattern worth noting is to implement the same business logic repeatedly in different controllers. Developers tend to copy and paste this logic, but they should be encapsulated in the service.
The best practice for building AngularJS applications is: the controller should not operate on DOM. Instead, the logic for accessing and
operating on DOM should be separated to commands. If there are some repeated logics between controllers, the biggest possibility is: we need to encapsulate these logics into a service. If a controller needs to use these functions, the AngularJS dependency injector should be used to inject the service.
The above is the content we learnt from AngularJS 1.x versions. It seems that the functions of controllers should be moved to the controllers in the commands. Because commands support injecting dependencies to APIs, they can forward the specific operations to the injected service for execution after receiving the user input. As a result, Angular 2 adopts a totally different implementation scheme and deletes the ng-controller command, solving the numerous controllers that exist everywhere from abuse of this command.


The data binding mechanism in AngularJS is implemented using the scope object. We first add various attributes on the scope object, and explicitly declare to bind these attributes in the template (one-way binding or two-way binding both work). This scheme looks clear, but the scope has another two more important responsibilities: dispatch events and implement dirty checking-based behavior. Angular beginners need to spend a lot of effort to understand the scope and how to use it. To this end, AngularJS 1.2 introduced the concept of a controller as syntax. It allows us to add attributes for the current context (this) inside the controller, so you don’t need to perform explicit injection of the scope object and then add attributes to the object. The code below demonstrates the simplified syntax:
Angular 2 makes a step forward that it deletes the scope object directly. All expressions are confined within the context of the
specific UI component. The deletion of the scope API greatly simplifies Angular 2. We don’t need explicit injection of scope any more. Instead, we only need to add the attributes to the UI component and perform the binding operation. Such an API is easier to use and more natural.

Dependency injection

In JavaScript circles, AngularJS 1.x may be the first framework that introduced the inversion of control (IoC) mechanism through dependency injection (DI). DI can bring many benefits, such as: testing friendliness, better code structures and modularization, as well as concision. DI works well in 1.x versions, but Angular 2 further gives play to it. Angular 2 is built based on the latest web standard, so it adopts ECMAScript 2016 decorator syntax to annotate the code that uses DI. The decorator here is very similar to the decorator in Python or the annotation in Java. They all can utilize the reflection to decorate the behavior of a specified object. But since the decorator is neither standardized, nor supported by mainstream browsers yet, some intermediate steps of conversion are required to use it. But if you don’t want the bother, you can write some lengthy code using ECMAScript 5 syntax to realize the same semantics.
The new version of DI is more flexible and more feature-rich, and eliminates some errors in AngularJS 1.x versions, such as the API inconsistency. In 1.x versions, some objects are injected based on the parameter order (for example, the scope, tag, attribute, and the controllers in command link functions), while other objects are injected based on the name (for example, injected based on the parameter name in the controller, command, service and filter).

Service end rendering

The higher the web demand, the more complicated the web application. To build a real single-page application requires a lot of JavaScript code. Including all the external class libraries used at one go will increase the size of scripts on the page to several megabytes. Application initialization on a mobile device may take several to a dozen seconds: obtaining all the resources from the service end, parse and execute JavaScript, render the page and apply all the styles. If you are using the wireless network on a low-end mobile device, this process may discourage you from accessing the application. Although some techniques can be used to accelerate the process, there are no silver bullets in complicated applications.
During their exploration for improving user experience, developers found the so-called server-side rendering technology. It renders the view requested by a single-page application on the service end, and directly sends the corresponding HTML to the users. After all the resources are processed, the script will add the event listener and bind the data. This looks like a good way to improve application performance. One of the pioneers using this method is ReactJS. It, utilizing Node.js DOM, achieves pre-rendering of user interface on the service end. Unfortunately, AngularJS 1.x architecture does not support this feature. The reason is that the framework and browser API are closely coupled. We have met the same problem during the dirty checking of WebWorker.
Another typical scenario of service-end rendering is: to build SEO-friendly (SEO stands for Search Engine Optimization) applications. To cover AngularJS 1.x applications in the search engine indexes, there have been many hacks. For example, there is a practical case like this: use a front-end-free browser to roam across the application, execute the script on each page and cache the rendering result into HTML files, so that the search engine can access the application.
Although this alternative can be used to build SEO-friendly applications, the adoption of service-end rendering technology can solve two problems mentioned previously: first, to improve the user experience, and second, to build SEO-friendly applications in a more simple and elegant way.
As long as we decouple Angular 2 and DOM, our applications can be run in an environment outside the browser. To achieve this purpose, the community has developed a tool which pre-renders the view in a single-page application on the service end and then forwards the view to the browser. When this part of the content was prepared, the tool was still in its early stage of development, so it is not included in the core of the framework.

Large-scale application

Ever since the emergence of Backbone.js, MVW has been standard configuration for building single-page applications. We can separate the business logic from the view according to the focal point separation principal to build a well-designed application. MVM offers the observer mode to listen to the changes to the data model and the view will be refreshed when changes occur. However, some explicit or implicit dependencies may exist between the event handlers, which makes the data streams in the application unclear and hard to comprehend. In AngularJS 1.x versions, different monitors can be dependent on each other. As a result, the digest loop has to perform traversing several times to get a stable result from these expressions. So Angular 2 adopts the one-way data stream design and its advantages are as follows:
•  More clear data streams.
•  No dependencies between different data bindings. So there is no TTL concept in the digest loop.
•  Higher performance: (1) The digest loop only runs once. (2) Applications that are friendly to the immutable/observable data models can be created for in-depth optimization.
The changes of data streams bring about another fundamental reform for the basic framework of AugularJS 1.x.
When we need to maintain a huge JavaScript-written code base, we may have to look at the data stream issue from a different angle. Although JavaScript duck typing (the dynamic feature of JavaScript objects - a note by the translator) makes this language flexible, it also increases the difficulty for code analysis and the support by IDE and text editors. The code refactoring for large projects becomes very hard and error-prone, because static analysis and type inference are impossible in most cases. Meanwhile, the absence of compilers leads to easy occurrence of typos which are hard to be detected before test cases or the real application are run.
Angular core teams decided to adopt TypeScript because of its better tools and type checks during compiling. The usage of TypeScript helps to improve development efficiency and reduce errors. As shown in the figure above, TypeScript is a superset of ECMAScript and introduces explicit type annotations and compilers. TypeScript code will be compiled into the common JavaScript supported by the current browser. From Version 1.6, TypeScript has implemented ECMAScript 2016 decorator. So it is a perfect option for Angular 2.
Various IDE and text editors are enabled with static code analysis and type checking for TypeScript. All these advantages contribute to reduction of errors so as to greatly improve development efficiency and simplify code refactoring. Another important implicit advantage of TypeScript is the performance enhancement from using static types, because JavaScript VM can optimize the static types during runtime.


The template is one of the core features of AngularJS 1.x. The template is a simple HTML page with no intermediate processing and compiling processes required. This is different from most of the template engines like mustache.js. The templates in AngularJS are concise and powerful. We can create Domain Specific Language (DSL) inside the template to expand HTML, as well as use custom tags and attributes.
Of course, this is also one of the major goals of web components. Previously, we have explained how Angular 2 leverages this new technology and the reason for using it. Although templates in AngularJS 1.x versions are powerful, a huge space for improvement remains. The templates of Angular 2 take the best of those in the previous version and solve some confusing problems, enhancing the functionality of the template.
Suppose we have created a command to allow users to pass a member attribute to it through the tag attribute. There are three different implementation methods in AngularJS 1.x:
If we have a user command and need to pass the name attribute to it, there are three different methods to achieve this (the content here seems to be repeated with the end of the previous paragraph, but this is what it is like in the original text - a note from the translator): the first method is to pass a‘literal’value; the second method is to pass a character string which can be executed as an ‘expression’in this case; and the third method is to pass an expression in pw_. The specific implementation of the command decides the syntax to be used, which leads to a mess in the command APIs and difficulty in remembering them.
In daily work, it is frustrating to deal with a lot of components developed based on different design schemes. To solve these problems, we need to introduce a universal convention. However, to achieve sound results and maintain API consistency, the community should agree on the decision.
Angular 2 provides special syntax for attributes to solve this issue. The attribute value will be executed in the context of the current component and different syntax is provided for passing the literal value.
From experiences with AngularJS 1.x, we have got used to another thing: the microsyntax used in the template commands, such as ng-if and nf-for. For example, in AngularJS 1.x versions, to traverse a user list and display user names, we can do the following:
Although this syntax looks intuitive, only a limited number of tools support it. So Angular 2 introduces clearer syntax to solve this problem, with richer semantics:
The code above clearly defines a user attribute which will be created in the context of iteration users.
But such syntax looks too lengthy for input. So developers can simplify the syntax as follows and compile it into a more lengthy form:

Dirty checking

In the section about WebWorker, we have mentioned the timing for running the digest loop in the context of other instantiated threads by WebWorker. Leveraging the code optimization mechanism of JavaScript VM, we can achieve significant performance improvement. One of the optimizations is called inline cache. But the memory usage efficiency of the digest loop in AngularJS 1.x versions is low and it also hinders the optimization process. Angular teams made a lot of research in this aspect and discovered various ways to improve the digest loop performance and efficiency. These discoveries have promoted the development of a brand new dirty checking mechanism.
For more flexibility, Angular teams extracted the dirty checking mechanism and decoupled it from the framework core. As a result, different dirty checking policies can be developed for tailored uses in different environments.
The result is: Angular 2 has two built-in dirty checking mechanisms:
• Dynamic dirty checking: similar to the dirty checking mechanism in AngularJS 1.x versions. Used in systems that do not allow eval(), such as CSP plug-ins and Chrome plug-ins.
• JIT dirty checking: it generates dirty checking code dynamically during runtime and allows JavaScript VM to conduct in-depth code optimization.
By now, we have discussed about why the latest version of JavaScript language should be used; why Web Component and WebWorker should be used; and why it is not worth the efforts to integrate all these powerful tools in AngularJS 1.x versions. New frameworks keep emerging one after another. You can only really identify their advantages or disadvantages after you have tried them yourself.

  • UID2865
  • Fans0
  • Follows0
  • Posts2
1st Reply#
Posted time:Jun 8, 2017 16:10 PM
The Information which you provided is very much useful for AngularJS Online Training Learners. Thank You for Sharing Valuable Information. AngularJS training free demo here! https://mindmajix.com/angularjs-training