March 7, 2016
  • All
  • Ionic
  • Top Posts

Angular is a Design Pattern

Max Lynch

CEO

angular-design-pattern

With Angular 2.0 fast approaching and the world of frontend frameworks in a massive transition, there’s been a lot of concern about the impending costs of moving to the next generation of Angular. Do developers have to learn yet another new framework?

Few teams have spent as much time with Angular 2 as the Ionic team has. We started building Ionic 2 back when Angular 2 was pre-alpha, with the dream of offering a faster, more standards-compliant, and future-proof mobile web framework than Angular 1 could provide.

One of the major realizations we’ve had from working on Ionic 2 is how similar Angular 2 and Angular 1 are at a high level, and how understanding this will help developers move from Angular 1 to Angular 2 far more easily. In many ways, Angular 2 isn’t really a new framework at all, just a new implementation of the same one we’ve come to know and love.

One framework, multiple implementations

With Angular 1, Angular 2, and Angular Dart, Angular has gone from a specific ES5 frontend framework, to a conceptual framework or design pattern with multiple implementations.

One can build UIs and frontend applications in the Angular style with a choice of at least three major language implementations: ES5, ES6/TypeScript, and Dart, though ES6/TypeScript is becoming the de facto Angular standard (i.e. don’t use Dart!).

If we take a closer look at how Angular apps work in each language, we start to see a ton of similarities. Let’s check out an example:

Example

To output a property from our scope or context, we can do this:

Angular 1:

<span>Today is {{todaysDate | date}}</span>

Angular Dart:

<span>Today is {{todaysDate | date}}</span>

Angular 2:

<span>Today is {{todaysDate | date}}</span>

Notice anything? They’re exactly the same! Let’s try a more complicated example with a theoretical list of songs:

In Angular 1 and Angular Dart:

<ion-list>
  <ion-item ng-repeat="song in songs" ng-click="openSong(song)">
    {{song.artist}} - {{song.title}}
    <span ng-if="song.isFavorite"><i class="icon ion-heart"></i></span>
  </ion-item>
</ion-list>

And Angular 2 (w/ Ionic 2):

<ion-list>
  <ion-item *ngFor="#song of songs" (click)="openSong(song)">
    {{song.artist}} - {{song.title}}
    <span *ngIf="song.isFavorite"><ion-icon name="heart"></ion-icon></span>
  </ion-item>
</ion-list>

Okay, we see more differences here, but the changes are well defined: ng-repeat is now ngFor, with a * used to denote this element as a template (that will be stamped out N times). Iteration uses “of” instead of “in” to grab the values of the list which is more inline with how iteration works in ES6 and TypeScript. We no longer use kebab-casing (i.e. ng-repeat) for attributes since Angular 2 decided to move to a more explicit naming convention (more on this).

If we apply a standard Angular 1 to Angular 2 syntax transformation, we have code that, conceptually, is identical to Angular 1 and Angular 2. We can look at this code and immediately understand the intention of it, assuming we’re already familiar with Angular.

Component Example

Most Angular users will find templates straight forward in Angular 2. A much bigger change comes with the new component model that replaces the directive/controller setup from Angular 1.

In Angular 1:

.controller('HomeCtrl', function($scope) {
  // controller for this "page"
})

.directive('profileImage', [function() {
  // ... directive here
}])

In Angular 2, since everything is a component, we can apply a simple transformation: turn controllers into components and turn ng1 directives into components.

Since Angular 2 lives and breathes TypeScript and ES6, we express “components” as classes that can (optionally) have a template attached. The analog to the above Angular 1 code would look like this in Angular 2:

import {Component} from 'angular2/core';

@Component({
    selector: 'home',
    template: '<div>home</div>'
})
export class HomeComponent { }

And the Angular 1 directive as an Angular 2 component:

@Component({
    selector: 'profile-image',
    template: '<div>profile image</div>'
})
export class ProfileImageComponent { }

Scope?

In Angular 1, scope was really just the “context” available to a region of the UI. For example, our profileImage directive might have a reference to the current user as part of its scope, or context, so it could render the user’s profile image.

This concept is exactly the same in ng2, except we use the natural ES6 concept of class instance data! Angular has gone from a custom context system to a standards-based approach since JavaScript has evolved to make this possible (with a little TypeScript decorator magic to make it cleaner):

export class ProfileImageComponent {
  @Input() user;

  clickFace() {
    // this.user is available, much like $scope.user would have been in ng1
  }
}

In Angular 2 we no longer need to have a custom $scope system to handle data for components, we get it for free* with ES6 and TypeScript!

*oversimplification, but it feels free to the end user!

Reducing the barrier to entry

Us Angular 1 veterans tend to forget how difficult it was to grok Angular 1. I know I had to take a month off from a lot of my other work to just understand what all these random terms like transclusion, directives, linking, scope, and so on actually meant.

A developer new to Angular and starting with Angular 2 will hopefully have way less domain-specific knowledge to learn since they can skip all the esoteric terms from Angular 1 and jump right into ES6/TypeScript code.

Plus, with no custom module system, Angular 2 code interops with the rest of the ES6 ecosystem, making it dead simple to install and import 3rd party code.

Angular all the way down

Once developers make the mental switch from the syntax of Angular 1 to Angular 2, we think they’ll find that they already know Angular 2. The concepts are practically identical, and the similarities don’t stop with templates and components; as users dig into pipes, dependency injection, and services, they’ll find tons of similar similarities (I like the sound of that).

Since there is so much overlap, we’ve tried to make Ionic 2 feel similar to Ionic 1, since it’s still based on Angular, just a new, better implementation of it! So far it seems to be going over really well and I’m optimistic that Angular 2 is going to be a major hit now that the dust is settling and the Angular 2 APIs are stabilizing.

Angular 2 is really just a better Angular!


Max Lynch

CEO