Angular - part 3

Angular

前言

繼續來寫Todo list的小專案吧

創建 Service

create_todo_service

// todo.service.ts
import { Injectable } from '@angular/core';
import { Todo } from './todo';
import { TODOS } from './mock-todos';


@Injectable({
  providedIn: 'root'
})
export class TodoService {

  constructor() { }

  getTodos(): Todo[] {
    return TODOS;
  }
}
// todos.component.ts
import { Component, OnInit } from '@angular/core';
import { Todo } from '../todo';
import { TodoService } from '../todo.service';

@Component({
  selector: 'app-todos',
  templateUrl: './todos.component.html',
  styleUrls: ['./todos.component.css']
})
export class TodosComponent implements OnInit {
  todos: Todo[];
  selectedTodo: Todo;

  constructor(
    private todoService: TodoService
  ) { }

  ngOnInit() {
    this.getTodos();
  }

  getTodos(): void {
    this.todos = this.todoService.getTodos();
  }

  onSelect(todo: Todo): void {
    this.selectedTodo = todo;
  }
}

增加 todos routing

將path設定在app-routing.modles.ts中, 如果在init時沒有出現這檔案,請執行ng generate module app-routing --flat --module=app

// app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { TodosComponent } from './todos/todos.component';

const routes: Routes = [
  { path: '', redirectTo: '/todos', pathMatch: 'full' },
  { path: "todos", component: TodosComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
<!-- app.component.html -->
<h1></h1>
<router-outlet></router-outlet>

試著連接看看http://localhost:4200/http://localhost:4200/todos

增加 todo detail routing

// todo.ts
export class Todo {
  "id": number;
  "title": string;
  "description": string;
}
// mock-todos.ts
import {Todo} from './todo';

export const TODOS: Todo[] = [
  {
    id: 1,
    title: 'Coding',
    description: 'Write some code.',
  },
  {
    id: 2,
    title: 'Eating',
    description: 'Eat some food.',
  },
  {
    id: 3,
    title: 'Sleeping',
    description: 'Want some sleep.',
  },
]
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { TodosComponent } from './todos/todos.component';
import { TodoDetailComponent } from './todo-detail/todo-detail.component'

const routes: Routes = [
  { path: '', redirectTo: '/todos', pathMatch: 'full' },
  { path: "todos", component: TodosComponent },
  { path: "detail/:id", component: TodoDetailComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
<!-- todos.component.html -->
<h2>Todo List</h2>
<ul class="todos">
  <li *ngFor="let todo of todos"
      (click)="onSelect(todo)"
      routerLink="/detail/"
  >
    <h4></h4>
    <p></p>
  </li>
</ul>
// todo.service.ts
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { Todo } from './todo';
import { TODOS } from './mock-todos';


@Injectable({
  providedIn: 'root'
})
export class TodoService {

  constructor() { }

  getTodos(): Observable<Todo[]> {
    return of(TODOS);
  }

  getTodo(id: number): Observable<Todo> {
    return of(TODOS.find(todo => todo.id == id));
  }
}
// todo-detail.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import {Todo} from '../todo';
import { TodoService }  from '../todo.service';

@Component({
  selector: 'app-todo-detail',
  templateUrl: './todo-detail.component.html',
  styleUrls: ['./todo-detail.component.css']
})
export class TodoDetailComponent implements OnInit {
  @Input() todo: Todo;

  constructor(
    private route: ActivatedRoute,
    private todoService: TodoService,
    private location: Location
  ) { }

  ngOnInit() {
    this.getTodo();
  }

  getTodo(): void {
    const id = +this.route.snapshot.paramMap.get('id');
    this.todoService.getTodo(id)
      .subscribe(todo => this.todo = todo);
  }
}

todo_detail_page

新增 back button

<!-- todo-detail.component.html -->
<div *ngIf="todo">
  <h2> Detail</h2>
  <div>
    <label>Description:</label>
    <p></p>
  </div>
</div>
<button (click)="goBack()">go back</button>
// todo-detail.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import {Todo} from '../todo';
import { TodoService }  from '../todo.service';

@Component({
  selector: 'app-todo-detail',
  templateUrl: './todo-detail.component.html',
  styleUrls: ['./todo-detail.component.css']
})
export class TodoDetailComponent implements OnInit {
  @Input() todo: Todo;

  constructor(
    private route: ActivatedRoute,
    private todoService: TodoService,
    private location: Location
  ) { }

  ngOnInit() {
    this.getTodo();
  }

  getTodo(): void {
    const id = +this.route.snapshot.paramMap.get('id');
    this.todoService.getTodo(id)
      .subscribe(todo => this.todo = todo);
  }

  goBack(): void {
    this.location.back();
  }
}

part3就先到這囉!