Getting started with Angular 2: Part 2

前端之家收集整理的这篇文章主要介绍了Getting started with Angular 2: Part 2前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Getting Started

In the first post,we used Angular CLI to generate the project skeleton,and used @H_301_3@ng serve to run this application on Angular CLI built-in webpack dev server.

Now we wil add more components,Angular CLI provides @H_301_3@ng generate to create a component quickly. Follow the steps that we have done in Getting started with Angular 1.5 and ES6,we will create a simple blog application.

You can get source codes from Github.

Generate posts component

Enter the project root folder,and generate a new component via:

ng g component posts

You will see the following info.

create src\app\posts\posts.component.css
create src\app\posts\posts.component.html
create src\app\posts\posts.component.spec.ts
create src\app\posts\posts.component.ts

By default,it will create a new folder under src\app folder,named posts. And the newly created component will be generated into the posts folder.

Have a look at the home of posts.component.ts file.

import { Component,OnInit } from '@angular/core';

@Component({
  selector: 'app-posts',templateUrl: './posts.component.html',styleUrls: ['./posts.component.css']
})
export class PostsComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

It declares a component named @H_301_3@PostsComponent.

posts.component.css is the component specific CSS style file used for @H_301_3@PostsComponent,posts.component.html is the template file for @H_301_3@PostsComponent.

posts.component.spec.ts is the unit test file.

import { TestBed,async } from '@angular/core/testing';
import { PostsComponent } from './posts.component';

describe('Component: Posts',() => {
  it('should create an instance',() => {
    let component = new PostsComponent();
    expect(component).toBeTruthy();
  });
});

Common page layout

Generally,a page layout could be consist of header,sidebar,home body,and footer section,and only home section are replaced with different home in different views.

In this sample,we will create a simple navbar as header and footer components to demonstrate common page layout.

Modify the @H_301_3@AppComponent template file app.component.html,which act as the template layout for all chidren components.

<app-navbar>
</app-navbar>
<h1>
  {{title}}
</h1>
<app-footer>
</app-footer>

I will try to use the same layout in my Angular 1.5 and ES6 sample.

In the project root folder,install bootstrap and Ng2Bootstrap(the Angular 2 compatible component and directives).

npm install ng2-bootstrap bootstrap@next --save

You should includes the bootstrap css file. Angular CLI leaves some room to extend. Add the bootstrap css path in angular-cli.json.

//...
  "styles": [
	"styles.css","../node_modules/bootstrap/dist/css/bootstrap.min.css"
  ],//...

Follow official Angular 2 style guild,generate navbar and footer components in app/shared folder.

Enter app/shared folder,execute the following command.

ng g component navbar --flat

--flat tells @H_301_3@ng command do not create a new folder for the created component.

It generates 4 files for navbar component,similar witht the former posts component.

Replace the template home of navbar.component.html file.

<nav class="navbar navbar-fixed-top navbar-light bg-faded">
  <div class="container">
    <a class="navbar-brand" [routerLink]="['/admin']" ><i class="fa fa-admin"></i>ANGULAR2 SAMPLE</a>
    <button class="navbar-toggler hidden-sm-up" type="button" data-toggle="collapse" data-target="#exCollapsingNavbar" aria-controls="exCollapsingNavbar2"
      aria-expanded="false" aria-label="Toggle navigation">
    ☰
  </button>

    <!-- Collect the nav links,forms,and other home for toggling -->

    <div class="collapse navbar-toggleable-xs" id="exCollapsingNavbar">
      <ul class="nav navbar-nav">
        <li class="nav-item" [routerLinkActive]="['active']"><a class="nav-link" [routerLink]="['/posts']"  >{{'posts'}}</a></li>
        <li class="nav-item" [routerLinkActive]="['active']"><a class="nav-link" [routerLink]="['/posts','new']"  >{{'new-post'}}</a></li>
        <li class="nav-item" [routerLinkActive]="['active']"><a class="nav-link" [routerLink]="['/about']"  >{{'about'}}</a></li>
      </ul>

      <!-- /.navbar-collapse -->
    </div>
  </div>
  <!-- /.container-fluid -->
</nav>

In this navbar template,it uses Bootstrap navbar component,and adds some links to different views. We will cover this links in Route section.

Similarly,generates footer component via:

ng g component footer --flat

Fill the following home in footer.component.html file.

<footer class="bg-faded" style="background-color: #e3f2fd;">
  <div class="container">
    <div class="row">
      <div class="col-md-6 ">
      </div>
      <div class="col-md-6">Copyright: HantsyLabs</div>
    </div>
  </div>
  <!-- /.container-fluid -->
</footer>

Since Angular 2.0 RC,a new router module is introduced for reorganizing the application logic structure. To use them,we have to import them in @H_301_3@AppModule and declares them in @H_301_3@declarations property of @H_301_3@NgModule annotation.

import {NavbarComponent} from './shared/navbar.component';
import {FooterComponent} from './shared/footer.component';

@NgModule({
declarations:[NavbarComponent,FooterComponent]
})
export class AppModule{}

A more flexible approach is creating a @H_301_3@SharedModule for these component fragments,directives,pipes,etc.

mport { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';

import { NavbarComponent } from './navbar.component';
import { FooterComponent } from './footer.component';


@NgModule({
  imports: [
    CommonModule,RouterModule
  ],declarations: [
    NavbarComponent,FooterComponent
    ],exports: [
    NavbarComponent,FooterComponent
  ],})
export class SharedModule { }

And import this module in @H_301_3@AppModule.

import { SharedModule } from './shared/shared.module';
//...

@NgModule({
  declarations: [
    AppComponent
  ],imports: [
  //...
  SharedModule,//...
  }]
export class AppModule { }

When this application is reloaded,you will see the app component is decorated with navbar and footer.

Route

To navigate between pages,you have to define routing rules to make all page oriented components work.

Generates some samples components/modules for demonstration.

In the project root folder,generates a admin and an about modules.

ng g component admin
ng g module admin --routing

It will generate admin component files,and two an extra file: admin.module.ts and admin-routing.module.ts.

Declares @H_301_3@AdminComponent in admin.module.ts.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AdminRoutingModule } from './admin-routing.module';
import { AdminComponent } from './admin.component';

@NgModule({
  imports: [
    CommonModule,AdminRoutingModule
  ],declarations: [AdminComponent]
})
export class AdminModule { }

In @H_301_3@admin.module.ts file,it imports another module file,admin-routing.module.ts.

import { NgModule } from '@angular/core';
import { Routes,RouterModule } from '@angular/router';
import { AdminComponent } from './admin.component';

const routes: Routes = [
  { path: 'admin',component: AdminComponent }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],exports: [RouterModule],providers: []
})
export class AdminRoutingModule { }

The routes defines the routing rules for this module,and we also wrap this definition in to a standard Angular 2 @H_301_3@NgModule.

Create another sample module,named @H_301_3@about.

ng g component about
ng g module about --routing

The home of about.module.ts:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AboutRoutingModule } from './about-routing.module';
import { AboutComponent } from './about.component';

@NgModule({
  imports: [
    CommonModule,AboutRoutingModule
  ],declarations: [AboutComponent]
})
export class AboutModule { }

The home of about-routing.module.ts:

import { NgModule } from '@angular/core';
import { Routes,RouterModule } from '@angular/router';

import { AboutComponent } from './about.component';

const routes: Routes = [
  { path: 'about',component: AboutComponent }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],providers: []
})
export class AboutRoutingModule { }

We have added admin and about link in navbar. Two directives are used: @H_301_3@routerLink and @H_301_3@routerLinkActive. @H_301_3@routerLink will process the target route and @H_301_3@routerLinkActive will toggle css class when the link is active or not.

Import these modules into app.module.ts.

import { AdminModule } from './admin/admin.module';
import { AboutModule} from './about/about.module';

@NgModule({
	//...
  imports: [
	//...
    AdminModule,AboutModule
  ],

Do not forget add route-outlet directive into app.component.html file.

<app-navbar></app-navbar>
<div class="page">
  <div class="container">
    <router-outlet></router-outlet>
  </div>
</div>
<app-footer></app-footer>

Add css to adjust the default layout,add the following into styles.css.

.page {
  margin-top: 80px;
  min-height: 600px;
}

Now run this application again,you could navigate between admin and about via links in navbar.

Loading module lazily

By default,as above settings,all modules will be loadded when application is started.

The new router supports loading modules lazily as possible.

Generates more componets in posts folder,such as new-post,post-details,edit-post.

ng g component new-post --flat
ng g component edit-post --flat
ng g component post-details --flat

Add these modules into posts.module.ts.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {FormsModule} from '@angular/forms';

import { PostsRoutingModule } from './posts-routing.module';
import { PostsComponent } from './posts.component';
import { NewPostComponent } from './new-post.component';
import { EditPostComponent } from './edit-post.component';
import { PostDetailsComponent } from './post-details.component';

@NgModule({
  imports: [
    CommonModule,FormsModule,PostsRoutingModule
  ],declarations: [
    PostsComponent,NewPostComponent,EditPostComponent,PostDetailsComponent
  ]
})
export class PostsModule { }

And defines routing rules in posts-routing.module.ts.

import { NgModule } from '@angular/core';
import { Routes,RouterModule } from '@angular/router';

import { PostsComponent } from './posts.component';
import { NewPostComponent } from './new-post.component';
import { EditPostComponent } from './edit-post.component';
import { PostDetailsComponent } from './post-details.component';

const routes: Routes = [
  { path: '',redirectTo: 'admin' },{ path: 'admin',component: PostsComponent },{ path: 'new',component: NewPostComponent },{ path: 'edit/:id',component: EditPostComponent },{ path: 'view/:id',component: PostDetailsComponent },];

@NgModule({
  imports: [RouterModule.forChild(routes)],providers: []
})
export class PostsRoutingModule { }

In @H_301_3@app-routing.module.ts file,add:

const routes: Routes = [
  { path: '',redirectTo: '/admin',pathMatch: 'full' }
  { path: 'posts',loadChildren: 'app/posts/posts.module#PostsModule' },];

The first routing defines an empty path property,it means this is the default path of this application. It will redirectTo /admin(the path of AdminComponent).

The second routing rule uses the lazy way to load PostsModule when navigates /posts prefix urls. At runtime,it will append /posts as prefix to all urls defined in the posts-routing.module.ts file.

You can add another routing to process the notfound path,use ** as path value,put this definition at the last postion of the routes array.

{ path: '**',component:PageNotFoundComponent}

Now try to navigate posts and new-post links in navbar,and notice the network tracking in your Chrome developer tools.

Display post list

Open src\app\posts\posts.components.ts file,add posts data in ngOnInit method.

export class PostsComponent implements OnInit {
  posts: Post[];

  constructor() { }

  ngOnInit() {
    this.posts = [
      {
        id: 1,title: 'Getting started with REST',home: 'Home of Getting started with REST',createdAt: '9/22/16 4:15 PM'
      },{
        id: 2,title: 'Getting started with AngularJS 1.x',home: 'Home of Getting started with AngularJS 1.x',{
        id: 3,title: 'Getting started with Angular2',home: 'Home of Getting started with Angular2',];
  }
}

Creat a new file src\app\posts\post.model.ts,it is a model class wrap the Post fields.

export interface Post {
  id?: number;
  title: string;
  home: string;
  createdAt?: string;
  createdBy?: string;
}

Add @H_301_3@import in src\app\posts\posts.component.ts.

import {Post} from './post.model';

Open src\app\posts\posts.components.html.

<div class="card">
  <div class="card-block bg-faded">
    <div class="row">
      <div class="col-md-9">
        <form class="form-inline" (ngSubmit)="search()">
          <div class="form-group">
            <input type="text" name="q" class="form-control" [(ngModel)]="q" />
          </div>
          <button type="submit" class="btn btn-outline-info">{{'search'}}</button>
        </form>
      </div>
      <div class="col-md-3">
        <span class="pull-md-right">
          <a class="btn btn-success" [routerLink]="['/posts','new']">new-post</a>
        </span>
      </div>
    </div>
  </div>
</div>

<div class="row">
  <div class="col-md-6" *ngFor="let post of posts ">
    <div class="card card-block">
      <h4 class="card-title">{{post.title}}</h4>
      <h6 class="card-subtitle text-muted">{{post.createdAt|date:'short'}}</h6>
      <p class="card-text">{{post.home}}</p>
      <div class="text-md-right">
        <a [routerLink]="['/posts','edit',post.id]">edit</a>
        <a [routerLink]="['/posts','view',post.id]">view</a>
      </div>
    </div>
  </div>
</div>

Save all files,when application is reloaded,navigate to http://localhost:4200/posts,you should see the following screen.

Try to click the edit and view links in each post card. It should route to the right component view.

Component lifecycle hooks

In @H_301_3@PostsComponent,there is a @H_301_3@ngOnInit method which is from @H_301_3@OnInit interface and it will be invoked when the component is initialized.

Inversely,when the component is being destroyed,there is a hook named @H_301_3@OnDestroy which has a method @H_301_3@ngOnDestroy which will be called.

Besides these generic lifecycle hooks,there are some other specific hooks available in Angular 2 for component lifecycle. Please read the official lifecycle hooks.

Summary

In this post,we created some components,and create a common layout for the chidren components. Also experienced the new Angular Router and used it to navigate between master view(@H_301_3@PostsComponent) and details view(@H_301_3@PostDetailsComponent).

猜你在找的Angularjs相关文章