欢迎来到 跌倒的小黄瓜 的博客

♪(^∇^*)我要当大佬,(#^.^#)哈哈哈哈,(。-ω-)zzz我要成为优秀的人,(*^▽^*)٩(๑>◡<๑)۶O(∩_∩)O哈哈~~~~~~~~欢迎━(*`∀´*)ノ亻!

ng-做一个简单的通讯录--学习使用路由和HTTP

app.module

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {FormsModule} from '@angular/forms';
import {HttpClientModule} from '@angular/common/http';
import {HTTP_INTERCEPTORS} from '@angular/common/http'

import {GlobalInterceptor} from './global.interceptor'

// 开启 HTTP 功能
// open the root AppModule,
// import the HttpClientModule symbol from @angular/common/http,
// add it to the @NgModule.imports array.

import { AppComponent } from './app.component';
import { NavbarComponent } from './navbar/navbar.component';
import { SidebarComponent } from './sidebar/sidebar.component';
import { SigninComponent } from './signin/signin.component';
import { SignupComponent } from './signup/signup.component';
import { ContactListComponent } from './contact-list/contact-list.component';
import { ContactNewComponent } from './contact-new/contact-new.component';
import { ContactEditComponent } from './contact-edit/contact-edit.component';
import { TagListComponent } from './tag-list/tag-list.component';
import { TagNewComponent } from './tag-new/tag-new.component';
import { TagEditComponent } from './tag-edit/tag-edit.component';
import { AppRoutingModule } from './/app-routing.module';
import { LayoutComponent } from './layout/layout.component';


@NgModule({
  declarations: [
    AppComponent,
    NavbarComponent,
    SidebarComponent,
    SigninComponent,
    SignupComponent,
    ContactListComponent,
    ContactNewComponent,
    ContactEditComponent,
    TagListComponent,
    TagNewComponent,
    TagEditComponent,
    LayoutComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    HttpClientModule
  ],
  providers: [{
    provide: HTTP_INTERCEPTORS,
    useClass: GlobalInterceptor,
    multi: true
  }],
  bootstrap: [AppComponent]
})
export class AppModule { }

路由模块



// 0. 路由模块初始化
// 1. 配置路由表
//    请求 xxx 路径的时候,导航到 xxx 组件
// 2. 配置路由出口及路由导航链接
import { NgModule }             from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import {AuthGuard} from './auth-guard.service'

import {LayoutComponent} from './layout/layout.component'

import {ContactListComponent} from './contact-list/contact-list.component'
import {ContactNewComponent} from './contact-new/contact-new.component'
import {ContactEditComponent} from './contact-edit/contact-edit.component'

import {TagListComponent} from './tag-list/tag-list.component'
import {TagNewComponent} from './tag-new/tag-new.component'
import {TagEditComponent} from './tag-edit/tag-edit.component'

import {SigninComponent} from './signin/signin.component'
import {SignupComponent} from './signup/signup.component'

const routes: Routes = [
  {
    path: '',
    redirectTo: '/contacts', // 当请求根路径的时候,跳转到 contacts 联系人组件
    pathMatch: 'full' // 必须完全匹配到路径的时候才做重定向
  },
  {
    // 当我们访问 contacts 的时候,会先把 LayoutComponent 组件渲染出来
    // 然后把 children 中 path 为空的路由渲染到 LayoutComponent 组件中的路由出口
    path: 'contacts',
    component: LayoutComponent,
    canActivate: [AuthGuard], // 在导航 contacts 之前会先进入路由守卫
    children: [
      {
        path: '',
        component: ContactListComponent
      },
      {
        path: 'new', // 这里的 new 的请求路径是  /contacts/new
        component: ContactNewComponent
      },
      {
        path: 'edit/:id', // 动态路径
        component: ContactEditComponent
      }
    ]
  },
  {
    // 当我们访问 contacts 的时候,会先把 LayoutComponent 组件渲染出来
    // 然后把 children 中 path 为空的路由渲染到 LayoutComponent 组件中的路由出口
    path: 'tags',
    component: LayoutComponent,
    canActivate: [AuthGuard],
    children: [
      {
        path: '',
        component: TagListComponent
      },
      {
        path: 'new', // 这里的 new 的请求路径是  /contacts/new
        component: TagNewComponent
      },
      {
        path: 'edit',
        component: TagEditComponent
      }
    ]
  },
  {
    path: 'signin',
    component: SigninComponent
  },
  {
    path: 'signup',
    component: SignupComponent
  }
]

@NgModule({
  imports: [
    RouterModule.forRoot(routes)
  ],
  exports: [ RouterModule ],
  providers: [AuthGuard]
})
export class AppRoutingModule {}

路由守卫

import { Injectable }     from '@angular/core';
import { CanActivate, Router }    from '@angular/router';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor (
    private router: Router
  ) {}
  canActivate() {
    const token = window.localStorage.getItem('auth_token')
    if (!token) {
      this.router.navigate(['/signin'])
      return false // 不能继续导航
    }

    // 如果验证通过,则放行,继续完成导航
    return true;
  }
}

统一处理认证

import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';

import {Observable} from 'rxjs/Observable';

@Injectable()
export class GlobalInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const token = window.localStorage.getItem('auth_token')
    const authReq = req.clone({headers: req.headers.set('X-Access-Token', token)});
    return next.handle(authReq);
  }
}

注册

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Router } from '@angular/router'

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

  signupForm = {
    email: '',
    password: ''
  }

  email_err_msg = ''

  // 在组件类中声明了一个私有成员 http 它的类型是 HttpClient
  // 那么 Angular 会自动去实例化 HttpClient 得到一个实例
  // 然后我们就可以在组件中使用 http 这个成员来调用一些请求方法了
  // 例如 http.get http.post...
  constructor(
    private http: HttpClient,
    private router: Router
  ) { }

  ngOnInit() {
  }

  signup() {
    // 1. 表单验证
    // 2. 获取表单数据
    // 3. 发起 http 请求和服务端交互
    // 4. 根据响应结果做交互处理
    const formData = this.signupForm
    this.http.post('http://localhost:3000/users', formData)
      .toPromise()
      .then((data: any) => {
        this.email_err_msg = ''
        window.localStorage.setItem('auth_token', data.token)
        window.localStorage.setItem('user_info', JSON.stringify(data.user))
        this.router.navigate(['/'])
      })
      .catch(err => {
        if (err.status === 409) {
          this.email_err_msg = '邮箱已被占用'
        }
      })
  }

}

登录

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Router } from '@angular/router'

@Component({
  selector: 'app-signin',
  templateUrl: './signin.component.html',
  styleUrls: ['./signin.component.css']
})
export class SigninComponent implements OnInit {
  signinForm = {
    email: '',
    password: ''
  }

  err_message = ''

  constructor(
    private http: HttpClient,
    private router: Router
  ) { }

  ngOnInit() {
  }

  signin () {
    this.http.post('http://localhost:3000/session', this.signinForm)
      .toPromise()
      .then((data: any) => {
        window.localStorage.setItem('auth_token', data.token)
        window.localStorage.setItem('user_info', JSON.stringify(data.user))
        this.router.navigate(['/'])
      })
      .catch(err => {
        if (err.status === 401) {
          this.err_message = '登陆失败,邮箱或密码错误'
        }
      })
  }
}

页面删除功能

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router'
import { HttpClient, HttpHeaders } from '@angular/common/http'

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

  public contacts: any

  constructor(
    private router: Router,
    private http: HttpClient
  ) { }

  ngOnInit() {
    this.getContacts()
  }

  getContacts() {
    this.http.get('http://localhost:3000/contacts')
      .toPromise()
      .then(data => {
        this.contacts = data
        console.log(this.contacts)
      })
      .catch(err => {
        console.log(err)
      })
  }

  deleteContactById(id, e) {
    e.preventDefault()
    if (!window.confirm('确定删除吗?')) {
      return
    }
    this.http.delete(`http://localhost:3000/contacts/${id}`)
      .toPromise()
      .then(data => {
        this.getContacts()
      })
      .catch(err => {
        console.log(err)
      })
  }

}

编辑

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'
import { HttpClient } from '@angular/common/http'

@Component({
  selector: 'app-contact-edit',
  templateUrl: './contact-edit.component.html',
  styleUrls: ['./contact-edit.component.css']
})
export class ContactEditComponent implements OnInit {
  formData = {
    name: '',
    email: '',
    phone: '',
    id: 0
  };

  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private http: HttpClient
  ) { }

  ngOnInit() {
    // 如何在组件中获取路由动态路径参数
    const contactId = this.route.snapshot.params.id
    this.getContactById(contactId)
  }

  getContactById (id) {
    this.http.get(`http://localhost:3000/contacts/${id}`)
      .toPromise()
      .then((data: any) => {
        this.formData = data
      })
      .catch(err => {
        console.log(err)
      })
  }

  editContact () {
    const id = this.formData.id
    this.http.patch(`http://localhost:3000/contacts/${id}`, this.formData)
      .toPromise()
      .then(data => {
        this.router.navigate(['/contacts'])
      })
      .catch(err => {
        console.log(err)
      })
  }

}

posted @ 2020-01-22 14:08  跌倒的小黄瓜  阅读(217)  评论(0编辑  收藏  举报