New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

100doc/day005 #1

Merged
merged 6 commits into from Jan 22, 2019
Merged
Diff settings

Always

Just for now

Copy path View file
@@ -1,7 +1,11 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { TodoPageComponent } from './pages/todo-page/todo-page.component';

const routes: Routes = [];
const routes: Routes = [
{ path: '', redirectTo: 'todo', pathMatch: 'full' },
{ path: 'todo', component: TodoPageComponent }
];

@NgModule({
imports: [RouterModule.forRoot(routes)],
Copy path View file
@@ -1,21 +1,3 @@
<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</div>
<h2>Here are some links to help you start: </h2>
<ul>
<li>
<h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
</li>
<li>
<h2><a target="_blank" rel="noopener" href="https://angular.io/cli">CLI Documentation</a></h2>
</li>
<li>
<h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
</li>
</ul>
<h2>todo app</h2>

<router-outlet></router-outlet>
Copy path View file
@@ -1,16 +1,26 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { TodoPageComponent } from './pages/todo-page/todo-page.component';
import { TodoListComponent } from './component/todo-list/todo-list.component';
import { TodoDetailComponent } from './component/todo-detail/todo-detail.component';

@NgModule({
declarations: [
AppComponent
AppComponent,
TodoPageComponent,
TodoListComponent,
TodoDetailComponent
],
imports: [
BrowserModule,
AppRoutingModule
AppRoutingModule,
HttpClientModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
@@ -0,0 +1,6 @@
<div>
<input type="text" [(ngModel)]="todo.task" (keyup.enter)="add()"
autofocus placeholder="add todo">
<input type="checkbox" [(ngModel)]="todo.done">
<button (click)="add()">add</button>
</div>
@@ -0,0 +1,31 @@
$margin: .5rem;
$padding: 10px;
$font-size: large;
$hover-color: lightyellow;

div {
margin: $margin;
}

input {
margin-left: $margin;

&[type="text"] {
font-size: $font-size;
padding: $padding;
border-width: 0px 0px 1px 0px;
width: 300px;
}
}

button {
margin-left: $margin;
font-size: $font-size;
padding: $padding;
width: 5rem;
border-radius: .5rem;

&:hover, &:focus {
background-color: $hover-color;
}
}
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { TodoDetailComponent } from './todo-detail.component';

describe('TodoDetailComponent', () => {
let component: TodoDetailComponent;
let fixture: ComponentFixture<TodoDetailComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ TodoDetailComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(TodoDetailComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,25 @@
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { Todo } from 'src/app/models/todo';

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

todo: Todo = new Todo;

@Output() clickAdd = new EventEmitter<Todo>();

constructor() { }

ngOnInit() {
}

add() {
this.clickAdd.emit(this.todo);
this.todo = new Todo;
}

}
@@ -0,0 +1,9 @@
<div *ngFor="let todo of list">
<label>{{todo.id.toString().padStart(3, '0')}}</label>

<input type="checkbox" [(ngModel)]="todo.done" (change)="upd(todo)">

<input type="text" [(ngModel)]="todo.task" [class.done]="todo.done">

<button (click)="del(todo)">del</button>
</div>
@@ -0,0 +1,35 @@
$margin: .5rem;
$padding: 10px;
$font-size: large;
$hover-color: lightyellow;

div {
margin: $margin;
}

input {
margin-left: $margin;

&[type="text"] {
font-size: $font-size;
padding: $padding;
border-width: 0px 0px 1px 0px;
width: 300px;
}
}

button {
margin-left: $margin;
font-size: $font-size;
padding: $padding;
width: 5rem;
border-radius: .5rem;

&:hover, &:focus {
background-color: $hover-color;
}
}

.done {
color: silver;
}
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { TodoListComponent } from './todo-list.component';

describe('TodoListComponent', () => {
let component: TodoListComponent;
let fixture: ComponentFixture<TodoListComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ TodoListComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(TodoListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,30 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { Todo } from 'src/app/models/todo';

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

@Input() list: Todo[] = [];

@Output() clickUpd = new EventEmitter<Todo>();

@Output() clickDel = new EventEmitter<Todo>();

constructor() { }

ngOnInit() {
}

upd(todo: Todo) {
this.clickUpd.emit(todo);
}

del(todo: Todo) {
this.clickDel.emit(todo);
}

}
Copy path View file
@@ -0,0 +1,5 @@
export class Todo {
id: number;
task: string;
done: boolean;
}
@@ -0,0 +1,7 @@
<app-todo-detail (clickAdd)="clickAdd($event)"></app-todo-detail>

<app-todo-list
[list]="todos"
(clickUpd)="clickUpd($event)"
(clickDel)="clickDel($event)"
></app-todo-list>
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { TodoPageComponent } from './todo-page.component';

describe('TodoPageComponent', () => {
let component: TodoPageComponent;
let fixture: ComponentFixture<TodoPageComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ TodoPageComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(TodoPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,36 @@
import { Component, OnInit } from '@angular/core';
import { TodoService } from 'src/app/services/todo.service';
import { Todo } from 'src/app/models/todo';

@Component({
selector: 'app-todo-page',
templateUrl: './todo-page.component.html',
styleUrls: ['./todo-page.component.scss']
})
export class TodoPageComponent implements OnInit {

todos: Todo[] = [];

constructor(private todoService: TodoService) { }

ngOnInit() {
this.todoService.get().subscribe(r => this.todos = r);
}

clickAdd(todo: Todo) {
this.todoService.add(todo).subscribe(
r => this.todos.push(r)
);
}

clickUpd(todo: Todo) {
this.todoService.upd(todo).subscribe();
}

clickDel(todo: Todo) {
this.todoService.del(todo).subscribe(
_ => this.todos = this.todos.filter(t => t.id !== todo.id)
);
}

}
@@ -0,0 +1,12 @@
import { TestBed } from '@angular/core/testing';

import { TodoService } from './todo.service';

describe('TodoService', () => {
beforeEach(() => TestBed.configureTestingModule({}));

it('should be created', () => {
const service: TodoService = TestBed.get(TodoService);
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,45 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Todo } from '../models/todo';

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

url = 'api/todos';

constructor(private http: HttpClient) { }

get(): Observable<Todo[]> {
return this.http.get<Todo[]>(this.url).pipe(
tap(r => this.log('get', r))
);
}

add(todo: Todo): Observable<Todo> {
return this.http.post<Todo>(this.url, todo).pipe(
tap(r => this.log('get', r))
);
}

upd(todo: Todo): Observable<Todo> {
return this.http.put<Todo>(`${this.url}/${todo.id}`, todo).pipe(
tap(r => this.log('get', r))
);
}

del(todo: Todo): Observable<object> {
return this.http.delete<Todo>(`${this.url}/${todo.id}`).pipe(
tap(r => this.log('get', r))
);
}

private log(operation: string, result: any) {
console.group(`TodoService::${operation}`);
console.log(result);
console.groupEnd();
}
}
ProTip! Use n and p to navigate between commits in a pull request.