The Official Ionic Blog

The next generation HTML5 hybrid app development SDK

Welcome to the second post in our series on Angular 2. If you missed the first post, check out the quick Intro to Angular 2.

In this post, we are going to talk about Components, which elegantly replace the mix of controllers, scopes, and directives from Angular 1.

The death of scope

If you missed Igor and Tobias’ great talk at ngEurope in October, they quite dramatically proclaimed the death of a variety of Angular 1 concepts, including controllers and $scope. I was there, I and remember the gasps and nervous laughter from the crowd as a series of ominous gravestones flashed on the screen:

RIP Angular 1

The uproar from the broader community was immediate, with scathing comments, high-profile departures, and plenty of overly-dramatic banter to make it really exciting.

Though it made for good TV, the reaction was unwarranted. Those new to Angular 2 quickly see how the new component model is a lot easier to use than what we had in v1.

The “Component”

Angular 1 wasn’t built around the concept of components. Instead, we’d attach controllers to various parts of the page with our custom logic. Scopes would be attached or flow through, based on how our custom directives encapsulated themselves (isolate scope, anyone?).

I don’t really know how to describe the model in v1, but it wasn’t like any other hierarchical system I’ve ever used. We’d just “attach” behaviors to various parts of our page and then have to deal with the complicated meta-structure created by our directives, controllers, and scopes.

To add logic to the page, we’d have to decide between building a controller or a custom directive.

In version 2, Angular drops all of this for a much cleaner, more object-oriented Component model.

Our first component

If you’ve ever written Java, C#, or any other language with strong OO patterns, you’ll immediately understand a component. It’s just a class that represents an element on the screen, with member-data that influences the way it looks and behaves.

Just like a JComponent subclass in Java (Swing), or a Control subclass in Windows Forms development.

Let’s see an example:


import {Component} from [email protected]/core'

@Component({
  selector: 'my-component',
  template: '<div>Hello my name is {{name}}</div>'
})

export class MyComponent {
  constructor() {
    this.name = 'Max'
  }
  sayMyName() {
    console.log('My name is', this.name)
  }
}

This creates a new component called MyComponent, which will be identified in markup as <my-component>, just like restrict: 'E' did in v1.

We can specify a template for the component with the template property in @Component annotation (annotations are an es6 extension added by both AtScript and TypeScript, though only TypeScript will be relevant going forward).

Member data

If we look closer at the example above, we don’t see $scope anywhere. Instead, we see this.name = 'Max', and a member function (“method”) called sayMyName(). If you’re familiar with Controller As syntax in v1, the use of this will look familiar to you.

Even so, this is different. When our component is “instantiated” and rendered on the page, we have an instance of our component. We can modify the instance data of that component, call methods on it, and pass it around to other components. It’s just an object!

More tangibly, imagine we have a Button component. The component has a this.title for the text of the button, and a click handler. Previously, we’d either build a new directive for the button, maybe add an isolate scope with some events and two-way data bindings, or get lazy and just attach a controller to it (or one of its parents). With Angular 2 components, we get a natural combination of all of these concepts: our Component has encapsulated instance data (much like isolate scopes), event handlers (much like methods attached to scopes), and a template (much like directives).

We can even inherit from other components or attach components through attributes, and access parents and siblings (more on that in a future post). This is a far easier, less error-prone way to replace require from directives in v1.

ngApp?

In the previous post, we briefly mentioned the bootstrap process, the process by which an Angular 2 app powers itself up. In v1, we had ng-app, or we could manually bootstrap. In v2, there isn’t an ng-app. Instead, we provide our own root Component from which we want to start the app:

<app></app>

which would look like this as a v2 component:


@Component({ 
  selector: 'app',
  templateUrl: 'main.html'
 })

class MyApp {
  constructor() {
    console.log('App Start')
  }
}

bootstrap(MyApp)

What we’d often see in Angular 1 was ng-app and ng-controller used on the same element, like this:

<body ng-app="myspace" ng-controller="AppCtrl">

Then, our AppCtrl would create some root scope data that our child controllers would access and/or extend.

In v2, we get all of that in one Component.

I really like this change. If you think about your document layout, it’s really just a tree. The root shouldn’t be any different than every other element, even though it was in v1.

With the change to the component model, we need to change our mindset a bit. Instead of attaching our custom logic to the page with controllers, we put that logic into components. If we want a certain part of the page needs business logic, we create a new component for it. If we are using an existing component but want to attach behavior to it, we can extend it.

Annotations

Let’s dig in a bit to the @Component annotation above. If you recall, these are extensions on ES6, which are becoming part of TypeScript which Angular 2 will use.

Basically, these annotations allow us to attach information to our component. We can configure the selector our Component will look for to instantiate itself (like <my-component>), and also set the template.

@Component is the core annotation, and has a few important parameters:

@Component({
  selector: 'my-component',
  providers: [MyService],
  // Url based template
  templateUrl: 'main.html',

  // Inline template
  template: `
    <div>
      <button></button>
      <ng-content></ng-content>
    </div>
  `,
  directives: [Button],
})

The selector param is the replacement for the auto-naming system of directives in v1 and is now explicit: you must set it to exactly what you want the new component to be named in markup. It works much like querySelector.

The providers param is part of the new Dependency Injection system, and configures which services we want to inject into our component (more on this in a later post).

We can use provide a template either inline, using template, or point to an external file using templateUrl. This similar to how we defined templates for custom directives in Angular 1. Notice the use of the awesome new backtick Template strings in ES6 that let us easily create multi-line templates!

We also reference the child directives we want to enable so they are compiled and instantiated (I hope this changes in the future so you don’t have to explicitly specify child directives).

Finally, we should note the <ng-content></ng-content> tag in our template. This is the new “ngTransclude” and specifies where child content will be injected. You can have multiple ones and target different spots to include child content (more on this in the future!)

Conclusion

A lot is changing in Angular 2, and few things as dramatically as the way we build and specify components on the page.

Though it’s scary to move on from our beloved scopes, controllers, and directives (concepts that we worked so hard to learn and learn to love), it’s really a wonderful thing. With the new component model, Angular is moving into much more familiar OO territory, and is setting itself up to work with the future of web standards, like Web Components and Shadow DOM.

Once you get used to the new model, it’s hard to go back. I think the community will learn to embrace the changes and appreciate how they make Angular 2 so much better.

In our next post, we will talk about “New-way” data binding: the untimely death of 2-way data binding! Stay tuned.

  • Fernando

    Awesome intro tutorial. The new angular kinda reminds me a little bit about react, which is good.

    • Vasile

      the new angular reminds about Adobe Flex 4 – welcome to 2010 !! πŸ™‚

      • Adam Argyle

        agreed! lot’s of things are starting to look like Flex, see Polymer!

      • AndiSun

        agreed!

  • http://livelyworks.net LivelyWorks

    This series is awesome!!
    Helping us to move towards Angular 2 Smoothly.

    Thank you

  • Arnold Krumins

    Really starting to like Angular 2. I can definitely see advantages.

  • Palle Simonsen

    Ionic have demonstrated the very best that can come out of (F)OSS development – an awesome framework, best-in-class, driven by talent, energy and seemingly good teamwork. The numbers speak for themselves as do the quality of many of the apps produced with Ionic.

    Angular2, however, demonstrates one of the biggest problems with (F)OSS development, namely the lack of accountability towards an installed base – one of the nicer comments I read were: “Wow. I do not envy the person who has to tell the boss that the entire project has to be scrapped by the end of 2015 or face going unsupported for the next 15+ years.”. On top of that Typescript is a language with mixed receptions.

    What I would like to know is what the Ionic team is thinking in terms of migration. Is it ‘scrap the old stuff and reprogram’ or are there any realistic means of reusing any factory, service, controller or template code? And if not; for how long will Ionic 1.x be supported and how?

    • mhevery

      In ng-conf, we have made a commitment to support v1 while significant people are still using it. So if you have an app in v1, you can stay using v1 and you will be supported, no need to upgrade.

      • Palle Simonsen

        Thanks for the update and the commitment.

    • http://ionicframework.com/ Adam Bradley

      Ionic 1.x will continue to be supported after Ionic2 comes out, same as Angular 1.x. Since Ionic2 is not completed yet we haven’t finalized a migration path, but there will be one for those who choose to upgrade.

      • Palle Simonsen

        Hi Adam,
        This is what I want to hear. It is understood that it is early days. I take it that you will convey more information on the roadmap when ready.

        Brgds, Palle

  • Tomasz
  • mhevery

    Thanks for the write up, I could not have said it better myself.

  • http://www.badpenguin.org/ Antonio Gallo

    So IONIC v1 will keep using angular v1 or will be soon migrated to v2? just to understand if i’ve to go back to jquery mobile or not πŸ˜› or search another way of doing those apps.

    • Denis Andrejew

      Ionic v1 will stay on Angular v1, Ionic v2 will be using Angular v2. Breaking the API means incrementing the major version number (1->2), so that’s what’ll be happening here.
      (Edit: It would be just really silly to give up and break Ionic v1 while it’s a perfectly working and valid version of Ionic in and of itself.)

  • szahn

    How would “scope” inheritance work in Angular 2? Would components then inherit from other components? Wouldn’t all this deep nesting of inheritance be an anti-pattern?

    • http://www.SoftwareShinobi.com Holt Mansfield

      So far as I know there is no scope inheritance. Which is probably a good thing as it makes it very difficult to reason about your code. I’ve stopped using scope inheritance completely in my 1.x apps.

      It’s convenient but can blow up in your face as complexity goes up.

  • http://mithun.io/ Mithun

    Is there any forked project of Ionic for Windows Phone support? I desperately need one! πŸ™ What I understand from the official Ionic team is that they have no plans to start supporting WP “now”. They just have it in their least-priority TODO list. So I really appreciate anyone to introduce me to frameworks that support WP (I want only Ionic fork. Not others unless they are as good as Ionic).

    • Mark Chipman

      Check out http://angularjs.meteor.com/ … watch the video. I think you’ll be able to create apps that will work on Windows Phone. They are also providing a meteor-ionic library. Pretty cool stuff.

      • http://mithun.io/ Mithun

        Thanks for the link, Mark! I’ll check that out! πŸ™‚

  • http://blog.getelementsbyidea.com/ Olivier Combe

    I was wondering if you were using the new router in ionic 2, or just waiting for a final release?
    Otherwise how do you manage the routes/states of your app?

    • yesimahuman

      Hey. That depends on a few factors. We need a router w/ non linearity like you see with a tree of UINavigationControllers (to use the native iOS example). We have been involved with the new router discussion, so I’m really optimistic, just need to wait a bit on it.

      That being said, we aren’t sure we want to do routing like we did in v1. It is pretty complicated, and we allow for pretty powerful deep linking that I’m not sure is worth the complexity (rarely do native apps deep link more than one history state deep, for UX reasons).

      I’d personally like seeing URLs take less of a role in v2 for hardcore internal routing, instead favoring states and local routing (push/pop inside the closest navigation stack).

      Stay tuned!

  • http://gattune.blog.br Calebe Aires

    AngularJS 2 has some point of ReactJS… Will Angular2 + Ionic go on the React Native way?

  • nielskrijger

    Looks a lot like Java’s JSF; which is not a good thing.

    How vague and abstract is the term “component”? Everything in the world is a component… Will it have complex component lifecycles also like JSF? These components need to be managed by something; which needs to be altered/extended on…

    Annotations I would regard as an anti-pattern really. The original branding/popularity of POJO’s was to simplify stuff; now check any Java codebase and those simple plain old java objects have become a wishwash of hundreds of annotations (I’m not joking, I wrote plenty myself).

    I’m particularly afraid this will be fun for some time learning a bit of new stuff, but looking back at your code two years later and I highly doubt it will feel clean or simple (not that angular 1 is clean or simple). Particularly with ES6 and ES7 in the future rendering typescript a bit unnecessary frankly.

  • Badru

    Thanks for sharing

  • Ryan King

    Are annotations required? This seems like a silly question, but it has been mentioned many times bye the Angular team that Angular 2 can be written with regular ES6. Any examples I have seen require developing in TypeScript simply because of the annotations.

    • evanplaice

      You can use ES6 with annotations in both Babel and Traceur. Babel requires an additional plugin + configuration. Traceur requires configuration.

      If you use JSPM + Traceur, add the following to config.js:

      traceurOptions: {
      “annotations”: true
      }

      Typescript is definitely not required, there’s just little/no documentation available for using Angular2 + ES6.

      If you’re curious and want to see NG2 + ES6 in action check out my site:
      https://github.com/evanplaice/evanplaice.com

  • Naveen Singh

    nice descriptive post, but i would like to know does angular-v2 keep support the two-way data-binding or it would move two one-way data binding.

  • Valiant200

    I am a bit worried that we are not seeing any es6 based tutorials.

  • rvanhoepen

    To be honest at first I was really against some of the changes coming in Angular 2, but these posts are really helping me see why these changes are going to be great and you are making me excited to start implementing them in my projects. Thanks for the time and effort you put into explaining the new concepts Max!

  • http://www.ronanconnolly.ie Ronan Connolly

    Coming from an OO software background using Java and C#, this is great news πŸ™‚
    Much more comfortable territory.

  • David Cornelson

    I’m still waiting for information on services. Did I miss that?

  • pacomerh

    This is good. Basically I needed a reason or a problem to solve to get into Angular, and mobile apps is a very good one.

  • http://www.wisamfadel.com Wisam Fadel

    Thanks you, I can’t wait for Angular 2

  • http://codetunnel.io/ Alex Ford

    So, to use Angular 2 do we HAVE to use the Typescript transpiler? I hate working with transpilers. Is there no way to use Angular 2 as plain JS?

    • evanplaice

      You don’t HAVE to use Typescript. You can use ES6 with Babel/Traceur + decorators enabled.

      You can also write pure ES5 but I don’t recommend it. Decorators are basically high-order wrapper functions that add a lot of additional functionality. Trying to replicate the same functionality in pure ES5 requires a lot of extra work.

    • Vance Feld

      typescript isn’t really a transpiler… it just removes itself πŸ™‚ (if you’re targeting es6)

  • ismavolk

    Thanks!

  • murali krishna N

    Hi Max,

    Thanks for your wonderful articles. I have a small doubt in Angular 2.0 as I started reading since yesterday.

    When everybody writing a component they were writing the class just below the Annotation section as below. Since we will write so many components in our projects lets say if I write two components in a single file in that case how the component decides which class it has to use.

    //Anotation section
    @Component({ selector: ‘app’ })
    @View({
    url: ‘main.html’,
    })
    //Component controller
    class MyApp {
    constructor() {
    console.log(‘App Start’)
    }
    }

    • evanplaice

      The decorator applies to the class directly following. The same way as it works in Python.

      As long as you do decorator first immediately followed by the class there won’t be any issues with putting multiple components in the same file.

  • Mikko KΓ€mΓ€rΓ€inen

    Web Components
    for those who want to try out components the easy way / online, no installations: I made a Codepen collection with starters for a few alternatives. Angular 2.0 and Aurelia are iframes to Plunker, as they require several .js ad .html files. Available starters currently for: Angular 2.0 preview, Angular 1.4 RC2 with ES6 via Babel (possible to create components 2.0 style), Polymer and of course Aurelia.

    Feel free to fork from: http://codepen.io/collection/XPYmZa/

  • http://www.mintlab.com.ar Fernando Perez

    great info, thanks!

  • Binh Thanh Nguyen

    Nice post

  • http://www.syntaxsuccess.com/ Torgeir

    I have been playing around with the incremental alpha releases and so far so good. Have added my poc work here in case you want to see some current examples: http://www.syntaxsuccess.com/viewarticle/angular-2.0-examples

  • Kerensky87

    These Angular 2 posts are a great resource for understanding the changes from v1. Please continue this series of blog posts!

  • Ajay Singh

    Just finished learning ionic/angular and was about to start building app with ionic1/angular1 and all of a sudden things chnged.but coming from OO background its looking better. Plus your blog is making it really easy to learn the new angular.
    Thanks

  • Mapleiny

    I’m doing something with Angular 2, and I’m wondering if I can change the directives array base on what i want. the the screen shoot may be show what I mean. thank you!!

  • Vance Feld

    does @View still apply? seems like you just specify the template right in the controller now? for RC1