📜 ⬆️ ⬇️

Angular 2.0.0-alpha for those who can't wait


Most recently (March 5-6), the ng-conf conference was held, and many reports on it were devoted to the upcoming release of Angular 2, even the alpha version was shown on several of them. Of course, after listening, I really wanted to try it personally. If you also can not wait - please under the cat.

In this article we will figure out where to get the build alpha version of Angular 2.0, create a small application on it - To-do list, and run it in a browser without full support for ECMAScript 6.

Angular 2 is very different from the current version, almost everything has been rethought. Many of the differences stem from the fact that it uses ES6 to the full extent with annotations and types, the developers call this language AtScript. Now, apparently, the Angular team began to work closely with Microsoft and development will be conducted on TypeScript , and after the release of its version 1.5, AtScript will be fully enabled.

The Angular 2 application now consists of components and is their tree. The idea is similar to Web-components , even the Angular 2 component markup is placed in the Shadow DOM. And if you are going to use Web-components in your application, or, for example, Polymer , then the syntax will be no different from using your own Angular 2 components. The components themselves are ES6 classes with annotations, no special syntax such as, for example, for directives in version 1.x is required. Services have now also become common classes, and thanks to support for typing in AtScript, you can inject them by type, without using the syntax. $ Inject or ngAnnotate.
')
Let's now try to create our first To-do application, and as we go, we'll figure out what and how.

Today, no browser supports all the functionality that Angular 2 needs to work, so we need a whole bunch of tools:

So that everyone who wants to feel the alpha does not have to put it all separately, the developers have collected quick start. It can be installed by typing in the project folder:

git clone https://github.com/angular/quickstart.git 

Now everything we need is in the quickstart folder, and for beauty we will add another angular-material , but of course we will use only css from it:

 bower install angular-material 

Now create the index.html file in the project:

 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>To Do</title> <script src="/quickstart/dist/es6-shim.js"></script> <link href="bower_components/angular-material/angular-material.css" rel="stylesheet" /> </head> <body layout="row"> <style> md-progress-circular.md-default-theme.blue .md-inner .md-right .md-half-circle { border-right-color: #039be5; } md-progress-circular.md-default-theme.blue .md-inner .md-left .md-half-circle, md-progress-circular.md-default-theme .md-inner .md-right .md-half-circle { border-top-color: #039be5; } md-progress-circular.md-default-theme.blue .md-inner .md-left .md-half-circle { border-left-color: #039be5; } md-progress-circular.md-default-theme.blue .md-inner .md-gap { border-top-color: #039be5; border-bottom-color: #039be5; } </style> <app flex layout="row" layout-fill> <div layout-fill layout="row" layout-align="center center" layout-margin> <md-progress-circular md-mode="indeterminate" class="md-default-theme blue" style="-webkit-transform: scale(1);"> <div class="md-spinner-wrapper"> <div class="md-inner"> <div class="md-gap"> </div> <div class="md-left"> <div class="md-half-circle"></div> </div> <div class="md-right"> <div class="md-half-circle"></div> </div> </div> </div> </md-progress-circular> <h4>    To do app is loading... </h4> </div> </app> <script> System.paths = { 'angular2/*': 'quickstart/angular2/*.js', 'rtts_assert/*': 'quickstart/rtts_assert/*.js', 'app/*': 'app/*.js' }; System.import('app/App'); </script> </body> </html> 


Here you should pay attention to three points:

First of all, we connected the es6-shim file, it carefully collected all of the above, which we need to run the application.

Next, pay attention to the app element. This will be our main component of the application. Now it just contains a markup with a spinner and the words To do app is loading ... it will be displayed until the angular loads the component class and replaces this markup with its template.

At the very bottom, we used the system.js library, it implements the ES6 module loading system. First, using System.paths, we set up the paths to the .js files, then using System.import, we downloaded the file with the app component, and he, in turn, already pulls behind him all the necessary libraries and components.

Now create the app folder and put the App.js file in it:

 import {Component, Template, bootstrap, Foreach} from 'angular2/angular2'; import {TodoStore} from 'app/TodoStore'; import {ItemEditor} from 'app/ItemEditor'; @Component({ selector: 'app', componentServices: [ TodoStore ] }) @Template({ url: 'app/todo.html', directives: [Foreach, ItemEditor] }) class App { constructor(store:TodoStore) { this.store=store; } } bootstrap(App); 


First, we import the Component, Template, Foreach classes from angular2.js, and from there we import the bootstrap function, already familiar to those who do not use the ng-app directive in version 1.x, it initializes the main component of the application, then we import the TodoStore classes from the app /todoStore.js (this will be the service responsible for working with the task list and storing it in the browser's localStorage) and ItemEditor from app / item-editor.js (this will be the component - a directive that displays the list item). We have not written them yet, so we will consider them later.

Next, we create an App class, the TodoStore class object is passed to the constructor using an injector, which we assign to the store property.

When declaring a class, we used the Component and Template annotations from angular2.js:
Component - the annotation that makes the class a component. The selector property is a selector that allows you to find an element in the markup template, we have an app element. The componentServices property is a list of classes for the injector.

Template - helps to specify a template for the component. The url property indicates the path where the template will be located, the directives property indicates the list of directives that are used in the markup of this template.

At the end of the file, we use the bootstrap function to initialize our main component.

Let's now create the file app / TodoStore.js:

 export class TodoStore { constructor() { this.load(); } save() { window.localStorage['todoItems']=JSON.stringify(this.items); } addItem(name, checked) { this.items.push(new Item(name,checked)); } clear() { this.items.length=0; } load() { this.items=[]; let itemsStr=window.localStorage['todoItems']; if(itemsStr) { JSON.parse(itemsStr).forEach((e) => { this.addItem(e.name, e.checked); }); } } } class Item { constructor (name, checked){ this.name = name; this.checked=checked || false; } toggleCheck() { this.checked=!this.checked; } } 

The TodoStore class has save (), load (), clear (), and addItem (name, checked) methods.

The task list itself will be stored in the items property. The save () method saves the value of the items property to localStorage. The clear () method clears the items property. The load () method loads all list items from localStorage and adds them to items using the addItem method. The addItem (name, checked) method takes the name of a list item, creates a new Item object and adds it to Items.

Next comes the declaration of the class Item, the constructor accepts the name - the name of the list item and checked - if it is marked as completed. The class also has a toggleCheck () method, which changes the checked value to the opposite.

Next, create the file app / todo.html with the main component template:

 <style> @import "../bower_components/angular-material/angular-material.css"; .md-primary { background-color: #039be5; color: white; } md-toolbar { background-color: #CFD8DC; } md-input-container { padding-bottom: 0; } </style> <div flex layout="column" layout-fill layout-margin> <md-toolbar class="md-primary"> <h2 class="md-toolbar-tools"> <span>To do list</span> </h2> </md-toolbar> <md-content layout="row" layout-align="center start" flex> <div flex="50" flex-md="80" flex-sm="100"> <div layout="row" layout-margin flex> <button flex class="md-button md-primary md-raised md-default-theme" (click)="store.save()">Save</button> <button flex class="md-button md-primary md-raised md-default-theme" (click)="store.load()">Load</button> <button flex class="md-button md-primary md-raised md-default-theme" (click)="store.clear()">Clear</button> </div> <div layout="row" layout-margin flex> <md-input-container class="md-input-has-value" flex="60"> <input #newitem class="md-input" placeholder="New to do item" /> </md-input-container> <button flex class="md-button md-primary md-raised md-default-theme" (click)="store.addItem(newitem.value)">Add new item</button> </div> <md-list> <md-item *foreach="#item in store.items"> <md-item-content> <item-editor [item]="item"></item-editor> </md-item-content> </md-item> </md-list> </div> </md-content> </div> 

Here we have three buttons that call the store.save (), store.load () and store.clear () methods. We bind to the click event of each button with an attribute (click). In the current version of the angulyar, it is sometimes quite difficult at first glance to distinguish in the markup which attribute is used to bind to the event and which is used to bind data, now everything will be immediately visible, parentheses () are needed to react to the events of the element or component, and the attribute in square brackets [] binds to the data, it is assumed that the attribute value is an expression that will be calculated, and its result will be assigned to the attribute of the element, if the attribute is specified without any brackets at all, it means in it a text value.

Next, let's pay attention to input with the #newitem attribute so we can now give the element a name by which it will be available to us, as in the click event below, where we take the value of the input'a newitem.value and pass it to store.addItem ()

Next comes the task list, which we derived using the new * foreach directive (this is a replacement for ng-repeat), here, as in input'e, we wrote #item to refer further to each element of the list named item.

We are going to display each element of the list with the help of the item-editor directive, with which we bind the list element with the help of the [item] attribute.

Now create the file app / ItemEditor.js with the ItemEditor component, which will be responsible for displaying the list items.

 import {Component, Template} from 'angular2/angular2'; @Component({ selector: 'item-editor', bind: { 'item': 'item' } }) @Template({ inline: ` <style> @import "../bower_components/angular-material/angular-material.css"; md-checkbox.md-checked .md-icon { background-color: #039be5; color: white; } </style> <md-checkbox [class.md-checked]="item.checked" (click)="item.toggleCheck()"> <div class="md-label"> <div class="md-container"> <div class="md-icon"></div> </div> <span> {{item.name}} </span> </div> </md-checkbox> ` }) export class ItemEditor { } 


Here in @Component we specified the 'item-editor' selector, this is the element that is used in * foreach in todo.html. Next is the bind property, which indicates that you need to bind the value of the item attribute to the item property of the component class (something like bindToController).

In Template , this time, instead of the url for the example, the inline property is specified, it serves to specify the text of the template directly in the code. This reduces the number of required HTTP requests, so after the release of Angular 2, some plug-in for Gulp is likely to appear, which will change the url to inline, to replace the current gulp-angular-templatecache .

In the template itself, you can see the attribute [class.md-checked] - this is a concise replacement of ng-class. And below is the name of the list item using the already-native syntax with curly braces {{item.name}}.

That's all, now you can run the project (checked only in Chrome) and see how the future Angular 2.0 works.

As we can see, the developers have completely rethought the concept of Angular.js and now we are waiting for a completely new framework with a new, more concise syntax. Thanks to a completely new architecture designed for large applications, rendering performance, the main scourge of versions 1.x, increases many times (a visual comparison can be seen at the end of the Dave Smith's report Angular + React = Speed ). The ability to use typing opens up prospects for the development of IDE for advanced support for code completion and static analysis (at least, Microsoft declares Angular support in Visual Studio as one of its priorities). And the innovations of ES6 will make the development even faster and more pleasant.

This is practically everything that I managed to learn about Angular 2.0 for today, we will continue to follow the news, but for now here are some interesting links on the topic:

Channel ng-conf on YouTube with lots of interesting reports
Angular 2.0 official website
Angular 2 Project on GitHub

Source: https://habr.com/ru/post/253469/


All Articles