How To Create Object In Angular 2
Introduction
With the release of Angular 2 just around the corner, it's important to have a grasp on the different concepts that this framework makes use of. Otherwise, it can be very easy to get confused while sifting through an Angular 2 project. In hopes of eliminating some of this confusion, I decided to create this article on the building block of Angular 2: the Component Directive (a.k.a. component).
To best illustrate this process, this post will take readers through the process of creating a top-level AppComponent
, as well as a nested component. Throughout this process, we are going to learn a great deal about integral parts of Angular spanning from its template syntax to its use of dependency injection.
The end goal of this tutorial is to create the Angular 2 application below.
View Scotch.io Angular 2 Component Example - Angular 2 RC.1 on plnkr
By the end of this tutorial, we will have a firm understanding of all of the different properties we can use to define components in Angular 2.
Before we begin working directly with components, let's quickly discuss why the Angular core development decided to make them the core part of the framework.
Components vs. Directives in Angular 1
The world of web development has changed tremendously 2009, which was the year when Angular 1 was initially released. Among the trends that continually rose during this time was the use of web components. When used, web components allow developers to gain total control over their webpage by providing highly functional templates that are encapsulated within custom HTML selectors.
After noticing their power, the Angular framework migrated from directives to components in Angular 2;
Components are simply directives that are always associated with a direct template.
This connection between the code and the template helps eliminate problems in Angular 1.x that developers were faced with. Among the more notable differences is the elimination of concepts like $scope
and transclusion
, which often made developing applications in Angular 1 a painful process.
Like HTML5 spec web components, Angular 2 components have an extremely well defined life-cycle. As a result of this, we can specify when different callback functions happen depending upon the state of a component. (For example, making a get
request to pulls data into a page once a component is initialized.)
When working with Angular components, we can make use of interfaces, like ngOnInit
and ngOnDestroy
, which allow us to implement functionality for different times in a component's lifecycle.
That being said, these interfaces Angular 2 provides developers with can be tremendously helpful and further show the ability to have complete control over any of our application's components.
Development Environment
Developing Angular 2 applications takes a bit of setup. You need to do things like:
- Grab all dependencies with npm
- Setup a transpiler. TypeScript in our case
- Start a server using something like
lite-server
While we'll go over setting up an Angular 2 application in another article, feel free to use the following blank Plunkr to start building your Angular 2 components.
View Angular 2 Getting Started Template - RC.1 on plnkr
Building a Top-Level Component
Applications built in Angular 2 always have a top-level component where all of the functionality lies, so let's get started by looking at this component and then go through the code line-by-line.
app/app.ts
/** ** First, we need to: ** 1a. import the Component class from @angular/core library ** 1b. import the bootstrap method from @angular/platform-browser-dynamic to load our web app */ import { Component } from '@angular/core'; // 1a import { bootstrap } from '@angular/platform-browser-dynamic'; // 1b /** ** 2a. Pass in the name for the HTML class selector (<my-app></my-app>) ** 2b. Set the styles of our component using the styles options ** 2c. Define our component's template inline, rather than using the templateUrl option to access an external file. **/ @Component({ // 2a selector: 'my-app', // 2b styles: [` h1 { color:#545454; background:#02A8F4; padding:15px; box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3); } `] // 2c template: ` <h1>Hello from the {{componentName}}.</h1> ` }) /** ** 3a. export our component so that it can be imported to other files ** **/ export class AppComponent { componentName: 'AppComponent' } bootstrap(AppComponent);
Let's break each step down so we can get a full understanding of how Angular 2 uses components.
Step 1: Import the Component Object
import { Component } from '@angular/core'
Angular 2 make use of the ES2015 module syntax (also known as ES6). For those unfamiliar with the syntax, it makes use of import
statements to access different pieces of code. In addition, the these import
statements, this syntax also relies upon export
statements to make code accessible to the rest of our application**.
When working with Angular 2, we will see these import
statements being used to gain access to core features of the framework through different Angular 2 libraries. In the code block we just looked at, we see the import
statement telling Angular that we want to access the Component
decorator from the @angular/core
library, which is one of the main libraries Angular 2 utilizes.
Below, we can check out some of the other APIs that are central to developing web applications in Angular 2.0.
-
@angular/http
- For making HTTP requests -
@angular/common
- Common core things including form validation -
@angular/router
- Routing for our entire app
@angular/http
As you may have guessed, this library gives us access to all of Angular 2's functionality regarding HTTP requests. The following script is required when using the HTTP library.
<script src="node_modules/@angular/bundles/http.dev.js"></script>
This library is a vital part of the framework. Often times we will see the HTTP_PROVIDERS
constants being imported from the @angular/http
library. Once imported, this variable can be passed into our component as a provider, which will grant that component access to Angular 2's core functionality.
@angular/common
The @angular/common
is frequently used to deal with form building. This library holds lies FORM_DIRECTIVES
constant which gives developers access to important directives like NgForm
and NgFormModel
.
The common library also provides developers with the validator and control functions, which can be used together to perform form validations. Angular and form validation is one of our favorite things here at Scotch, so you'll be sure to see an article coming soon on Angular 2 form validation.
@angular/router
The @angular/router
libraries hold all of the code necessary to implement client-side routing. The following script is required:
<script src="node_modules/@angular/bundles/router.dev.js"></script>
The @angular/router
is used to access the features like the @RouterConfig[]
decorator and the RouterLink
Directive.
When working in Angular 1.x, we were forced to use entire libraries (such as ngMessages
, and this resulted in poor performance since we had to load the entire library for all our pages. To help ease this, the ES2015 module syntax allows us to decouple parts of a library, such as @angular/core
, and access only the sections of code that we need.
Once the Component
object is imported, we can then begin describing our component using TypeScript's @
symbol. By checking out Angular 2's API guide, we can see that decorators are used to create new instances of @Directive
, @Injectable
, @RouterConfig
and more.
A Quick Note On Decorators
When building applications with Angular 2, we will be using the @
decorator all the time to create dif. In our example, we are using this decorator to create a new component. Once Angular sees this, it will know that we want to create a new instance of a component, and it will create our component according to our configuration.
app/app.ts
import { Component } from '@angular/core' @Component({ selector: 'my-app', providers: [], services: [], styles: [` h1 { color:#545454; background:#02A8F4; padding:15px; box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3); } `] template: ` <h1 class="main-text">Hello from the {{ componentName }}.</h1> ` })
Angular 2 Metadata
The main objective of these decorators is to allow us to add meta-data to our application that will tell Angular 2 how to process a class.
When building Angular components, we are able to configure the following options:
- selector - defines the name of the HTML tag where this component will live. In this case, our component will be shown through the
<my-app></my-app>
tags. - providers - This is where we pass in any services that want a component to access. We won't be getting into services in this article, however, they are used to handle data and play the part of services, providers, and factories Angular 1.
- directives - We use the directive option when we want to access another component directive. Because this is the top-level component, we often see components being passed into this option, and we will see how this works shortly
- styles - The styles option is used to style a specific component. One of the advantages of using components is their ability to encapsulate their styles. We could have just as easily linked to an external stylesheet by using the styleUrls property. We should note that an array of stylesheets can be passed into this option.
- template - This is the portion of our component that holds our template. It is an integral part of the component as it allows us to tie logic from our component directly to a view. When defining a template, we can either write it inline, or we can opt to use
templateUrl
to link to an external template.
Now that we've defined all the parts of our component, the last step is to export it so it can be used in other parts of our application.
Step 3: Export the Component
The exported class is where we can define any variables or functions that our component's template will be using:
app/app.ts
export class AppComponent { componentName: 'AppComponent' }
As we learned earlier, Angular 2 makes use of the ES2015 module syntax. By using the export
statement, this component can be imported into different files in a project so it is a pivotal part of Angular 2.
Step 4: bootstrap
our Component
app/app.ts
import { bootstrap } from '@angular/platform-browser-dynamic' /** @Component Configuration **/ bootstrap(AppComponent)
In Angular 1, we used the ng-app
directive to bootstrap Angular applications. In Angular 2, applications rely upon the bootstrap method to load top-level components.
Angular 2 was built with the intention of being completely decoupled from the DOM. We can just as easily run our application as a web-worker; however, we are using the framework to build a web application so we need to import this platform-specific method from @angular/platform-browser-dynamic
.
Angular 2 for Mobile Applications
We called bootstrap()
from the @angular/platform-browser-dynamic
library. So does this mean we can use a different bootstrap
method for different platforms? Absolutely!
NativeScript is a runtime for build mobile applications created by Telerik. The Nativescript team has created the nativescript-angular
library which I highly recommend checking out! This library grants us the nativeScriptBootstrap()
method, which allows developers to leverage the Angular framework to build Native mobile applications.
To learn more about how Angular 2 can be used to build NativeScript applications, you can check out the following links:
- Nativescript-Angular Library
- AngularConnect - Building native mobile apps with Angular 2 0 and NativeScript - Sebastian Witalec
- Angular 2.0 x NativeScript TodoMVC Stater
Back to bootstrapping; by passing in the name of our component to this method, we are bootstrapping our AppComponent, and we can pretty much think of this as a fancy word for loading; however, we do need to note that the bootstrap()
method vital part of Angular 2 as it loads our top-level component.
When working with large applications, it is best practice to keep this bootstrap method in a file of its own because the main component will often be accompanied by other providers that the app may depend upon, however, placing it inside this file was appropriate in the context of this getting started article.
And thus concludes our first look at a component in Angular 2. Once our app is bootstrapped, we can then add the appropriate HTML tags to our index.html
file:
<my-app>Loading ngFor Demo ...</my-app>
Watch as it appears! Although we're not done just yet, we can see a live demo of this in plnkr below.
View Scotch.io Angular 2 Component Example - Angular 2 RC.1 on plnkr
At this point in our tutorial, the code for our component should replicate the block below:
app/app.ts
import { Component } from '@angular/core'; import { bootstrap } from '@angular/platform-browser-dynamic'; @Component({ selector: 'my-app', styles: [` h1 { color:#545454; background:#02A8F4; padding:15px; box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3); } `] template: ` <div> <h1>Hello from the {{componentName}}.</h1> </div> ` }) export class AppComponent { componentName: 'AppComponent' } bootstrap(AppComponent)
Nesting A Child Component
Now that we have created a top-level component, let's take this one step further by creating a child component.
Let's look at doing the following with our child component:
- Use Angular 2's built-in directives (not to be confused with Components)
- Use a service to get data
- Loop over that data in our template
This section is going to take a look at Angular 2's new template syntax and show the basics of Dependency Injection and working with services.
The file structure for this project is going to look like the tree below. So far in our project, we have created the app/app.ts
files, however, we are now going to add the following friend.component.ts
and friend.service.ts
files.
|-- app/friend.component.ts |-- app/friend.service.ts |-- app/app.ts |-- index.html |-- config.js
Defining the Child Component Template
To get started, I am going to tell Angular that I want this component to live inside of <my-friends></my-friends>
. The template attached to this component is going to use the ngFor
structural directive to iterate over a list of names.
Angular 2 Template Syntax
ngFor is the new ng-repeat
The ngFor
directive is the successor to ng-repeat
, one of Angular 1.x's most popular directives. In addition to ngFor
, Angular 2 provides developers with a handful of other camel-case directives that come in the form of:
- attributes
- structural directives
In this example, we are going to make use of ngFor
, which is a structural directive. A structural directive is a directive that modifies the structure of the DOM.
Below we have the code for our template. In addition to the ngFor
statement, I am also going to create another componentName
variable just like we saw in the AppComponent
example. We can use the same variable name and not have to worry about it messing with other components that utilize the same naming conventions.
app/friend.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'my-friends' template: ` <h1>Hello from the {{ componentName }}!</h1> <div *ngFor="#f of friends"> <h3>Name: {{ f.name }}</h3> <h4>Age: {{ f.age }}</h4> </div> ` })
Whenever we see an asterisk (*
) prepended onto a directive, we immediately know that this is will be using templates tags (<template></template>
) to render this piece of code.
This ability to use symbols to create dynamic behavior is what Angular calls "syntactical sugar". It makes the process of developing web applications a quicker process by cutting out bits of unnecessary code without cluttering up our template.
Let's take a look at some other symbols that we will come across when working with Angular 2.
Angular 2 Syntax Overview
Local Variables #
The pound symbol (#
is used to declare a local variable in our templates. When working with templates in Angular 2, we can use this symbol to reference different DOM elements in our application. These local variables will act as references to specific DOM elements. Moreover, they provide us with the ability to do things like pull values from input fields and add dynamic functionality to a DOM element.
<div *ngFor="#f of friends">
Event Bindings ()
In Angular 1.x, we had to rely on directives like ng-click
, ng-blur
, ng-mouseenter
, to handle different events. Angular 2 has dropped all of these directives and implemented a new, powerful syntax that allows developers to bind to any valid DOM event. For example:
- click
- dblclick
- dragstart
- etc
By passing in the name of the event into parenthesis, which signifies an event binding in Angular 2. When working with events in Angular, it's important to know that events flow out of the template to the component.
<a (click)="doSomething()">Doing Something Button</a>
Property Binding []
On the opposite side of event bindings (()
) lie Angular's square-bracket syntax ([]
) which signifies a property binding.
When working with property bindings, any values flow from the component class to the template, whereas event bindings work vice-versa.
When working with Angular 1.x, we had to use directives like ng-src
and ng-href
to dynamically pass in values to DOM elements, however, the use of property bindings allows us to drop the ng-
prefix, and simply pass in the name of the property we wish to define.
<img [src]="someUrl" />
The use of property bindings is particularly key when defining attribute directives. For example, we can use the following syntax when working with NgStyle
<div [style.background]="colorValue"></div>
Now that we've learned a little bit about Angular's new template syntax, let's get back to our example and add some styles to our child component.
Child Component Styles
The first thing we'll do is style the div
that contains the ngFor
that iterates over through the friends
loop so that it creates individual cards for each person with some space between them. When we nest this component, we will wrap our main component's template in a div to see how the styling of a component will only have an effect on the template with which it is attached.
In addition to the div
class, we are also going to style the h1
so that the text aligns to the center of the page. Soon, we are going to see how these styles do not bleed into other components. For those who wish to learn more about styling components in Angular 2, you can check out our tutorial on styling components in Angular 2.
app/friend.component.ts
selector: 'my-friends' , styles: [` div { background-color:#EFEFEF; margin-bottom:15px; padding:15px; border:1px solid #DDD; box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3); border-radius:3px; } h2 { text-align: center; } `]
Export the FriendComponent Class
Once our styles are set, we need to export our newly made component using the export class ..
statement. Inside this class, I am going to create a friends object which will contain name
and age
properties that ngFor
will iterate over.
app/friend.component.ts
export class FriendComponent { componentName: 'FriendComponent'; friends = [ { age: 40, name: 'Jordan Houston' }, { age: 23, name: 'Josh Beh' }, { age: 23, name: 'Joseph Canina' }, { age: 24, name: 'Alexandra Wilkins' }, { age: 22, name: 'Kiersten Costanzo' }, { age: 23, name: 'Ku Sherwood' }, { age: 25, name: 'Arta Halili' }, { age: 21, name: 'Patrick Cooney' }, { age: 21, name: 'Z.A. Perr' }, { age: 18, name: 'Tyler Mulligan' }, { age: 26, name: 'Dennis Dempsey' }, { age: 32, name: 'Francis Yeager' }, { age: 23, name: 'Phil Belardi' }, { age: 25, name: 'Bryan Roman' } ]; }
Before we move forward, we have to take a quick detour and update our FriendComponent so that we can access this data.
Detour: Refactoring FriendComponent Class to use @Injectable()
We usually access data by using services and often times these services make use of another amazing feature of Angular 2: Dependency Injection and the use of @Injectable
. To understand the basics of how this works, let's move our friends
object so that it lies within a file located at app/friend.service.ts
.
The final code for this file is going to look like the block below.
app/friend.service.ts
// Step 1. Import Injectable Decorator import { Injectable } from '@angular/core'; // Step 2. Use @Injectable() to declare the FriendSerivce class as an Injectable @Injectable() /** Step 3A. - Create and export FriendsService Class { } 3B: create friends object and declare it to be an Array of any values/ 3C: Add friends object to the constructor function 3D: create getFriends() function to call all friends values. **/ // 3A export class FriendService { // 3B friends:Array<any>; // 3C constructor() { this.friends = [ { age: 40, name: 'Jordan Houston' }, { age: 23, name: 'Josh Beh' }, { age: 23, name: 'Joseph Canina' }, { age: 24, name: 'Alexandra Wilkins' }, { age: 22, name: 'Kiersten Costanzo' }, { age: 23, name: 'Ku Sherwood' }, { age: 25, name: 'Arta Halili' }, { age: 21, name: 'Patrick Cooney' }, { age: 21, name: 'Z.A. Perr' }, { age: 18, name: 'Tyler Mulligan' }, { age: 26, name: 'Dennis Dempsey' }, { age: 32, name: 'Francis Yeager' }, { age: 23, name: 'Phil Belardi' }, { age: 25, name: 'Bryan Roman' } ]; } // 3D getFriends() { return this.friends; } }
- The first thing we need to do is import Injectable from the
@angular/core
library. - Once that is imported, we then need to declare this class to be an injectable using the
Injectable()
decorator we just imported. When implemented,@Injectable()
decorator will tell that Angular a class needs to be used for dependency injection.
app/friend.service.ts
import { Injectable } from '@angular/core' @Injectable()
3a. We create our FriendService class which will wrap all of the code we want our FriendComponent
to access.
3b. We create a friends
variables, and use TypeScript's type-system to tell Angular that this object is going to be an array.
3c. We add our data to the friends object by adding it into our constructor function, which is where we put the data we want a particular class to receive.
3d. Lastly, we create a getFriends
function to return our array of items. This is where we will often see http
calls being made however our data is internal, therefore we can leave out having to import
the @angular/http
library.
Modifying Our FriendComponent File
Once our service is created, we need to do a few things in order to access it into our component. Let's import the service into our app/friend.component.ts
file.
app/friend.component.ts
import { Component } from '@angular/core'; // NEW ==> We need to import FriendService into our component import { FriendService } from 'app/friend.service';
Register the Service as A Provider
The next thing we need to do is pass FriendService
into our components providers option. As we learned earlier, this is the section of our component where we add any services that it makes use of.
app/friend.component.ts
@Components({ selector: 'my-friends', providers: [FriendService], styles: /** Styles are placed here **/ })
Inject it into our constructor() function
In order for our template to access the FriendService, we must inject it into the components constructor function. In this example, we are going to set our FriendService
equal to _friendService
.
Once it's added to our constructor function, we are going to finish things off by assigning the friends
variable the result of our getFriends()
function.
app/friend.component.ts
export class FriendComponent { componentName: 'FriendComponent'; // Inject FriendService and assign it to _friendService constructor(private _friendService: FriendService) { // Utilize .get request from app/friend.service.ts to populate friends object this.friends = _friendService.getFriends(); } }
Once things are all said in done, the final code for our app/friend.component.ts
should look like the block below:
app/friend.component.ts
import { Component } from '@angular/core'; import { FriendService } from 'app/friend.service'; @Component({ selector: 'my-friends', providers : [FriendService], styles: [` div { background-color:#EFEFEF; margin-bottom:15px; padding:15px; border:1px solid #DDD; box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3); border-radius:3px; } h2 { text-align: center; } `] template: ` <h2>Hello from the {{componentName}}!</h2> <div *ngFor="#f of friends"> <h4> Name : {{f.name}} </h4> <h4>Age: {{f.age}}</h4> </div> ` }) export class FriendComponent { componentName: 'FriendComponent'; // Inject FriendService and assign it to _friendService constructor(_friendService: FriendService) { // Utilize .get request from app/friend.service.ts to populate friends object this.friends = _friendService.getFriends(); } }
Additionally, the final code for our app/friend.service.ts
file should replicate the following code.
app/friend.service.ts
// Step 1. Import Injectable Decorator import { Injectable } from '@angular/core'; // Step 2. Use @Injectable() to declare FriendsSerivce to be used in DI/ @Injectable() /** Step 3A. - Create and export FriendsSerivce Class { } 3B - create friends object and declare it to be an Array of any values/ 3C Add friends object to the constructor function 3D: create getFriends() function to call all friends values. **/ // 3A export class FriendService { // 3B friends:Array<any>; // 3C constructor() { this.friends = [ { age: 40, name: 'Jordan Houston' }, { age: 23, name: 'Josh Beh' }, { age: 23, name: 'Joseph Canina' }, { age: 24, name: 'Alexandra Wilkins' }, { age: 22, name: 'Kiersten Costanzo' }, { age: 23, name: 'Ku Sherwood' }, { age: 25, name: 'Arta Halili' }, { age: 24, name: 'Patrick Cooney' }, { age: 23, name: 'Z.A. Perr' }, { age: 18, name: 'Tyler Mulligan' }, { age: 26, name: 'Dennis Dempsey' }, { age: 32, name: 'Francis Yeager' }, { age: 23, name: 'Phil Belardi' } ]; } // 3D getFriends() { return this.friends; } }
Now that we have successfully created a child component, we will finish this tutorial off by nesting it into our main AppComponent
Adding FriendComponent to AppComponent
Now that our second component is wired up, we are ready to nest it within our top-level component. To accomplish this, we need to make a few modifications to our app.ts
file.
We have already seen how we can import core parts of Angular 2 via the ES2015 module syntax. Now, let's check out how we can use these same import
statements to access code inside of our project.
app/app.ts
import { Component } from '@angular/core'; import { bootstrap } from '@angular/platform-browser-dynamic'; /** Nested Component */ import { FriendComponent } from 'app/friend.component';
Once our component is imported into the file, we then need to modify the sections of our @Component
instance:
In order to access FriendComponent
, we need to add it into the components directive
array.
app/main.component.ts
directives: [FriendComponent]
We need to add <my-friends></my-friends>
to our inline template or else it's not going to render. In addition to adding this tag, I also want to wrap this template in the <div>
tag that I spoke about earlier to further show Angular 2's style encapsulation.
Now, our code should show:
app/app.ts
import { Component } from '@angular/core'; import { bootstrap } from '@angular/platform-browser-dynamic'; /** Nested Component */ import { FriendComponent } from 'app/friend.component'; @Component({ selector: 'my-app', directives: [FriendComponent], styles: [` h1 { color:#545454; background:#02A8F4; padding:15px; box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3); } `] template: ` <div> <h1>Hello from the {{ componentName }}.</h1> <my-friends></my-friends> </div> ` }) export class AppComponent { componentName: 'AppComponent'; } bootstrap(AppComponent)
Conclusion
View Scotch.io Angular 2 Component Example - Angular 2 RC.1 on plnkr
By taking a look at our code, we see that we have successfully nested our FriendComponent
within our top-level AppComponent
. Additionally, we learned a great deal about components and the different parts that go into building them and tying them together, which is crucial when working with Angular 2.
In most cases, the component we nested into AppComponent
will be also a parent component that may consist of any number of children. We just saw how easy Angular makes the process of establishing this relationship.
Specifically, we learned that we only need to pass them in as a directive
into the parent components where they are being utilized. From there, the parent component will carry any of the templates associated with its child components as well as the functionality that goes along with it, and as a result of this, the child component will be rendered wherever and whenever its parent component is instantiated.
It's a simple process, yet it is still unbelievably effective. I hope you've learned at least something new about Angular 2's use of components in addition to gaining some knowledge regarding the rest of the framework!
As Angular 2 continues its final stride towards production, the attainment of all of this new knowledge will surely pay off in the long run.
How To Create Object In Angular 2
Source: https://www.digitalocean.com/community/tutorials/creating-your-first-angular-2-components
Posted by: leboeuffroir2002.blogspot.com
0 Response to "How To Create Object In Angular 2"
Post a Comment