[Share]Angular 2: Experience learnt from AngularJS 1.x
Created#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.
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
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.
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.
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:
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.
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