├── README.md
├── angular2-basic-todolist
├── .gitignore
├── .vscode
│ └── settings.json
├── LICENSE
├── README.md
├── app
│ ├── about
│ │ ├── about.component.css
│ │ ├── about.component.html
│ │ ├── about.component.ts
│ │ └── about.routes.ts
│ ├── app.component.css
│ ├── app.component.html
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── app.routes.ts
│ ├── main.ts
│ └── todo
│ │ ├── detail
│ │ ├── detail.component.css
│ │ ├── detail.component.html
│ │ └── detail.component.ts
│ │ ├── item
│ │ ├── item.component.css
│ │ ├── item.component.html
│ │ └── item.component.ts
│ │ ├── list
│ │ ├── list.component.css
│ │ ├── list.component.html
│ │ └── list.component.ts
│ │ ├── todo.module.ts
│ │ ├── todo.routes.ts
│ │ ├── todo.service.ts
│ │ └── todo.ts
├── index.html
├── package.json
├── styles.css
├── systemjs.config.js
├── tsconfig.json
└── typings.json
├── angular2-forms-tutorial
├── .gitignore
├── LICENSE
├── README.md
├── app
│ ├── app.component.css
│ ├── app.component.html
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── app.routes.ts
│ ├── main.ts
│ ├── reactive-forms
│ │ ├── reactive-forms.component.css
│ │ ├── reactive-forms.component.html
│ │ ├── reactive-forms.component.ts
│ │ └── reactive-forms.routes.ts
│ ├── template-forms
│ │ ├── template-forms.component.css
│ │ ├── template-forms.component.html
│ │ ├── template-forms.component.ts
│ │ └── template-forms.routes.ts
│ └── validators
│ │ └── mobile.validator.ts
├── index.html
├── package.json
├── styles.css
├── systemjs.config.js
├── tsconfig.json
└── typings.json
├── angular2-routes-guards-resolve
├── .gitignore
├── .vscode
│ └── settings.json
├── LICENSE
├── README.md
├── app
│ ├── app.component.css
│ ├── app.component.html
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── app.routes.ts
│ ├── home
│ │ ├── home.component.css
│ │ ├── home.component.html
│ │ └── home.component.ts
│ ├── main.ts
│ ├── services
│ │ ├── account.ts
│ │ └── auth.service.ts
│ └── todo
│ │ ├── detail
│ │ ├── detail.component.css
│ │ ├── detail.component.html
│ │ └── detail.component.ts
│ │ ├── item
│ │ ├── item.component.css
│ │ ├── item.component.html
│ │ └── item.component.ts
│ │ ├── list
│ │ ├── list.component.css
│ │ ├── list.component.html
│ │ └── list.component.ts
│ │ ├── todo.guards.ts
│ │ ├── todo.module.ts
│ │ ├── todo.resolver.ts
│ │ ├── todo.routes.ts
│ │ ├── todo.service.ts
│ │ └── todo.ts
├── index.html
├── package.json
├── styles.css
├── systemjs.config.js
├── tsconfig.json
└── typings.json
└── angular2-routes-lazy-module-webpack
├── .editorconfig
├── .gitignore
├── README.md
├── angular-cli.json
├── e2e
├── app.e2e-spec.ts
├── app.po.ts
└── tsconfig.json
├── karma.conf.js
├── package.json
├── protractor.conf.js
├── src
├── app
│ ├── app.component.css
│ ├── app.component.html
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── app.routes.ts
│ ├── home
│ │ ├── home.component.css
│ │ ├── home.component.html
│ │ └── home.component.ts
│ ├── index.ts
│ ├── lazy
│ │ ├── lazy.component.html
│ │ ├── lazy.component.scss
│ │ ├── lazy.component.spec.ts
│ │ ├── lazy.component.ts
│ │ ├── lazy.module.ts
│ │ └── lazy.routing.module.ts
│ ├── services
│ │ ├── account.ts
│ │ └── auth.service.ts
│ └── todo
│ │ ├── detail
│ │ ├── detail.component.css
│ │ ├── detail.component.html
│ │ └── detail.component.ts
│ │ ├── item
│ │ ├── item.component.css
│ │ ├── item.component.html
│ │ └── item.component.ts
│ │ ├── list
│ │ ├── list.component.css
│ │ ├── list.component.html
│ │ └── list.component.ts
│ │ ├── todo.guards.ts
│ │ ├── todo.module.ts
│ │ ├── todo.resolver.ts
│ │ ├── todo.routes.ts
│ │ ├── todo.service.ts
│ │ └── todo.ts
├── assets
│ └── .gitkeep
├── environments
│ ├── environment.prod.ts
│ └── environment.ts
├── favicon.ico
├── index.html
├── main.ts
├── polyfills.ts
├── styles.css
├── test.ts
├── tsconfig.json
└── typings.d.ts
└── tslint.json
/README.md:
--------------------------------------------------------------------------------
1 | # angular2-tutorial
2 | 博客 http://codin.im/ 中所有的教程源代码和实例。
3 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | dist
3 | node_modules
4 | typings
5 | *.log
6 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "./node_modules/typescript/lib"
3 | }
--------------------------------------------------------------------------------
/angular2-basic-todolist/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Mavlarn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/README.md:
--------------------------------------------------------------------------------
1 |
2 | # angular2-basic-todo
3 | 教程 [Angular2入门教程-2 实现TodoList App](http://codin.im/2016/09/15/angular2-tutorial-2-todolist-app/) 的项目源代码。
4 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/about/about.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mavlarn/angular2-tutorial/6fb614e815700cdd055f0558845852fa7e43b797/angular2-basic-todolist/app/about/about.component.css
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/about/about.component.html:
--------------------------------------------------------------------------------
1 |
About angular2-basic
2 |
3 | Just a simple example project to get started with Angular. Now includes routes!
4 |
5 | 返回
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/about/about.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'about',
5 | templateUrl: 'app/about/about.component.html',
6 | styleUrls: ['app/about/about.component.css']
7 | })
8 | export class AboutComponent { }
9 |
10 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/about/about.routes.ts:
--------------------------------------------------------------------------------
1 | import { Route } from '@angular/router';
2 |
3 | import { AboutComponent } from './about.component';
4 |
5 | export const AboutRoutes: Route[] = [
6 | {
7 | path: 'about',
8 | component: AboutComponent
9 | }
10 | ];
11 |
12 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/app.component.css:
--------------------------------------------------------------------------------
1 |
2 | h1 {
3 | width: 100%;
4 | font-size: 100px;
5 | font-weight: 100;
6 | text-align: center;
7 | color: rgba(175, 47, 47, 0.15);
8 | -webkit-text-rendering: optimizeLegibility;
9 | -moz-text-rendering: optimizeLegibility;
10 | text-rendering: optimizeLegibility;
11 | }
12 |
13 | footer {
14 | position: fixed;
15 | bottom: 30px;
16 | right: 50px;
17 | }
18 | footer .about {
19 | border-radius: 3px;
20 | background-color: lightgray;
21 | padding: 5px 15px;
22 | text-decoration: none;
23 | color: gray;
24 | }
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 | Todos
3 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'root-app',
5 | templateUrl: 'app/app.component.html',
6 | styleUrls: ['app/app.component.css']
7 | })
8 |
9 | export class AppComponent {
10 | }
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { RouterModule } from '@angular/router';
4 | import { FormsModule } from '@angular/forms';
5 |
6 | import { AppComponent } from './app.component';
7 | import { AboutComponent } from './about/about.component';
8 | import { TodoModule } from './todo/todo.module';
9 | import { routes } from './app.routes';
10 |
11 | @NgModule({
12 | imports: [BrowserModule, FormsModule, RouterModule.forRoot(routes), TodoModule],
13 | declarations: [AppComponent, AboutComponent],
14 | bootstrap: [AppComponent]
15 | })
16 | export class AppModule {}
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/app.routes.ts:
--------------------------------------------------------------------------------
1 | import { Routes } from '@angular/router';
2 |
3 | import { AboutRoutes } from './about/about.routes';
4 | import { TodoRoutes } from './todo/todo.routes';
5 |
6 | export const routes: Routes = [
7 | {
8 | path: '',
9 | redirectTo: '/todo/list',
10 | pathMatch: 'full'
11 | },
12 | ...AboutRoutes,
13 | ...TodoRoutes
14 | ];
15 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
6 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/todo/detail/detail.component.css:
--------------------------------------------------------------------------------
1 |
2 | .form-group label {
3 | display: inline-block;
4 | width: 100px;
5 | }
6 | .form-group p {
7 | display: inline-block;
8 | }
9 | a {
10 | border: solid 1px gray;
11 | border-radius: 3px;
12 | padding: 5px 20px;
13 | text-decoration: none;
14 | color: gray;
15 | cursor: pointer;
16 | }
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/todo/detail/detail.component.html:
--------------------------------------------------------------------------------
1 | 任务详情
2 |
3 |
25 | 返回
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/todo/detail/detail.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { ActivatedRoute, Router, Params } from '@angular/router';
3 |
4 | import { Todo } from '../todo';
5 | import { TodoService } from '../todo.service';
6 |
7 | @Component({
8 | selector: 'todo-detail',
9 | templateUrl: 'app/todo/detail/detail.component.html',
10 | styleUrls: ['app/todo/detail/detail.component.css']
11 | })
12 | export class TodoDetailComponent implements OnInit {
13 | selectedTodo: Todo;
14 | constructor(private route: ActivatedRoute,
15 | private router: Router,
16 | private todoService: TodoService) {}
17 |
18 | ngOnInit() {
19 | // this.route.params.forEach((params: Params) => {
20 | // let todoId = +params['id']; // (+) converts string 'id' to a number
21 | // this.selectedTodo = this.todoService.getTodoById(todoId);
22 | // if (!this.selectedTodo) {
23 | // this.router.navigate(['/todo/list']);
24 | // }
25 | // });
26 |
27 | let todoId = +this.route.snapshot.params['id'];
28 | let type = this.route.snapshot.params['type'];
29 | console.log('type in params:' + type);
30 | type = this.route.snapshot.queryParams['type'];
31 | console.log('type in queryParams:' + type);
32 | this.selectedTodo = this.todoService.getTodoById(todoId);
33 | if (!this.selectedTodo) {
34 | this.router.navigate(['/todo/list']);
35 | }
36 | }
37 | goBack() {
38 | window.history.back();
39 | }
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/todo/item/item.component.css:
--------------------------------------------------------------------------------
1 |
2 | .todo-item .toggle {
3 | text-align: center;
4 | width: 40px;
5 | height: 40px;
6 | position: absolute;
7 | top: 0;
8 | bottom: 0;
9 | margin: auto 0;
10 | border: none; /* Mobile Safari */
11 | -webkit-appearance: none;
12 | appearance: none;
13 | }
14 |
15 | .todo-item .toggle:after {
16 | content: url('data:image/svg+xml;utf8,');
17 | }
18 |
19 | .todo-item .toggle:checked:after {
20 | content: url('data:image/svg+xml;utf8,');
21 | }
22 |
23 | .todo-item label {
24 | word-break: break-all;
25 | padding: 15px 60px 15px 15px;
26 | margin-left: 45px;
27 | display: block;
28 | line-height: 1.2;
29 | transition: color 0.4s;
30 | }
31 | .completed {
32 | background: lightyellow;
33 | }
34 | .todo-item.completed label {
35 | color: #d9d9d9;
36 | text-decoration: line-through;
37 | }
38 |
39 | .todo-item .destroy {
40 | display: none;
41 | position: absolute;
42 | top: 0;
43 | right: 10px;
44 | bottom: 0;
45 | width: 40px;
46 | height: 40px;
47 | margin: auto 0;
48 | font-size: 30px;
49 | color: #cc9a9a;
50 | margin-bottom: 11px;
51 | transition: color 0.2s ease-out;
52 | background: none;
53 | border: none;
54 | }
55 |
56 | .todo-item .destroy:hover {
57 | color: #af5b5e;
58 | }
59 |
60 | .todo-item .destroy:after {
61 | content: '×';
62 | }
63 |
64 | .todo-item:hover .destroy {
65 | display: block;
66 | }
67 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/todo/item/item.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/todo/item/item.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, ViewEncapsulation } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { Todo } from '../todo';
4 | import { TodoService } from '../todo.service';
5 |
6 | @Component({
7 | selector: 'todo-item',
8 | templateUrl: 'app/todo/item/item.component.html',
9 | styles: ['.completed { background: lightgreen; }'],
10 | styleUrls: ['app/todo/item/item.component.css'],
11 | encapsulation: ViewEncapsulation.Native
12 | })
13 | export class TodoItemComponent {
14 | @Input() todo: Todo;
15 |
16 | constructor(private todoService: TodoService, private router: Router) {
17 | }
18 |
19 | gotoDetail(todo) {
20 | this.router.navigate(['/todo/detail', todo.id], {queryParams: {type: 'ok'}});
21 | }
22 |
23 | toggleTodoComplete(todo) {
24 | this.todoService.toggleTodoComplete(todo);
25 | }
26 | removeTodo(todo) {
27 | this.todoService.deleteTodoById(todo.id);
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/todo/list/list.component.css:
--------------------------------------------------------------------------------
1 |
2 | button {
3 | margin: 0;
4 | padding: 0;
5 | border: 0;
6 | background: none;
7 | font-size: 100%;
8 | vertical-align: baseline;
9 | font-family: inherit;
10 | font-weight: inherit;
11 | color: inherit;
12 | -webkit-appearance: none;
13 | appearance: none;
14 | -webkit-font-smoothing: antialiased;
15 | -moz-osx-font-smoothing: grayscale;
16 | }
17 |
18 | :focus {
19 | outline: 0;
20 | }
21 |
22 | .hidden {
23 | display: none;
24 | }
25 |
26 | .todoapp {
27 | background: #fff;
28 | margin: 50px 0 40px 0;
29 | position: relative;
30 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
31 | 0 25px 50px 0 rgba(0, 0, 0, 0.1);
32 | }
33 |
34 | .todoapp input::-webkit-input-placeholder {
35 | font-style: italic;
36 | font-weight: 300;
37 | color: #e6e6e6;
38 | }
39 |
40 | .todoapp input::-moz-placeholder {
41 | font-style: italic;
42 | font-weight: 300;
43 | color: #e6e6e6;
44 | }
45 |
46 | .todoapp input::input-placeholder {
47 | font-style: italic;
48 | font-weight: 300;
49 | color: #e6e6e6;
50 | }
51 |
52 | .new-todo,
53 | .edit {
54 | position: relative;
55 | margin: 0;
56 | width: 100%;
57 | font-size: 24px;
58 | font-family: inherit;
59 | font-weight: inherit;
60 | line-height: 1.4em;
61 | border: 0;
62 | color: inherit;
63 | padding: 6px;
64 | border: 1px solid #999;
65 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
66 | box-sizing: border-box;
67 | -webkit-font-smoothing: antialiased;
68 | -moz-osx-font-smoothing: grayscale;
69 | }
70 |
71 | .new-todo {
72 | padding: 16px 16px 16px 60px;
73 | border: none;
74 | background: rgba(0, 0, 0, 0.003);
75 | box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
76 | }
77 |
78 | .main {
79 | position: relative;
80 | z-index: 2;
81 | border-top: 1px solid #e6e6e6;
82 | }
83 |
84 | .todo-list {
85 | margin: 0;
86 | padding: 0;
87 | list-style: none;
88 | }
89 |
90 | .todo-list todo-item {
91 | position: relative;
92 | font-size: 24px;
93 | border-bottom: 1px solid #ededed;
94 | display: list-item;
95 | }
96 |
97 | .todo-list todo-item:last-child {
98 | border-bottom: none;
99 | }
100 |
101 | .footer {
102 | color: #777;
103 | padding: 10px 15px;
104 | height: 20px;
105 | text-align: center;
106 | border-top: 1px solid #e6e6e6;
107 | }
108 |
109 | .footer:before {
110 | content: '';
111 | position: absolute;
112 | right: 0;
113 | bottom: 0;
114 | left: 0;
115 | height: 50px;
116 | overflow: hidden;
117 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
118 | 0 8px 0 -3px #f6f6f6,
119 | 0 9px 1px -3px rgba(0, 0, 0, 0.2),
120 | 0 16px 0 -6px #f6f6f6,
121 | 0 17px 2px -6px rgba(0, 0, 0, 0.2);
122 | }
123 |
124 | .todo-count {
125 | float: left;
126 | text-align: left;
127 | }
128 |
129 | .todo-count strong {
130 | font-weight: 300;
131 | }
132 |
133 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/todo/list/list.component.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/todo/list/list.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { Todo } from '../todo';
4 | import { TodoService } from '../todo.service';
5 |
6 | @Component({
7 | selector: 'todo-list',
8 | templateUrl: 'app/todo/list/list.component.html',
9 | styleUrls: ['app/todo//list/list.component.css']
10 | })
11 | export class TodoListComponent {
12 | newTodo: Todo = new Todo();
13 | constructor(private todoService: TodoService) { }
14 |
15 | addTodo() {
16 | if (!this.newTodo.title.trim()) {
17 | return;
18 | }
19 | this.todoService.addTodo(this.newTodo);
20 | this.newTodo = new Todo();
21 | }
22 | get todos() {
23 | return this.todoService.getAllTodos();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/todo/todo.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule } from '@angular/forms';
4 |
5 | import { TodoListComponent } from './list/list.component';
6 | import { TodoDetailComponent } from './detail/detail.component';
7 | import { TodoItemComponent } from './item/item.component';
8 | import { TodoService } from './todo.service';
9 |
10 | @NgModule({
11 | imports: [CommonModule, FormsModule ],
12 | declarations: [TodoListComponent, TodoDetailComponent, TodoItemComponent],
13 | providers: [TodoService]
14 | })
15 | export class TodoModule {}
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/todo/todo.routes.ts:
--------------------------------------------------------------------------------
1 | import { Route } from '@angular/router';
2 |
3 | import { TodoListComponent } from './list/list.component';
4 | import { TodoDetailComponent } from './detail/detail.component';
5 |
6 | export const TodoRoutes: Route[] = [
7 | {
8 | path: 'todo/list',
9 | component: TodoListComponent
10 | },
11 | {
12 | path: 'todo/detail/:id',
13 | component: TodoDetailComponent
14 | }
15 | ];
16 |
17 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/todo/todo.service.ts:
--------------------------------------------------------------------------------
1 | import {Injectable} from '@angular/core';
2 | import {Todo} from './todo';
3 |
4 | @Injectable()
5 | export class TodoService {
6 |
7 | // 为了生成一个自增的id,保存最后一个生成的id
8 | lastId: number = 0;
9 | todos: Todo[] = []; // 任务列表
10 |
11 | constructor() {}
12 |
13 | // 添加一个任务
14 | addTodo(todo: Todo): TodoService {
15 | if (!todo.id) {
16 | todo.id = ++this.lastId;
17 | }
18 | this.todos.push(todo);
19 | return this;
20 | }
21 |
22 | // 从任务列表里删除一个任务
23 | deleteTodoById(id: number): TodoService {
24 | this.todos = this.todos.filter(todo => todo.id !== id);
25 | return this;
26 | }
27 |
28 | // 更新一个任务
29 | updateTodoById(id: number, values: Object = {}): Todo {
30 | let todo = this.getTodoById(id);
31 | if (!todo) {
32 | return null;
33 | }
34 | Object.assign(todo, values);
35 | return todo;
36 | }
37 |
38 | getAllTodos(): Todo[] {
39 | return this.todos;
40 | }
41 |
42 | getTodoById(id: number): Todo {
43 | return this.todos.filter(todo => todo.id === id).pop();
44 | }
45 |
46 | // 标记一个任务为完成/未完成
47 | toggleTodoComplete(todo: Todo){
48 | let updatedTodo = this.updateTodoById(todo.id, {
49 | complete: !todo.complete
50 | });
51 | return updatedTodo;
52 | }
53 | }
--------------------------------------------------------------------------------
/angular2-basic-todolist/app/todo/todo.ts:
--------------------------------------------------------------------------------
1 | export class Todo {
2 | id: number;
3 | title: string = '';
4 | createdDate: Date = new Date();
5 | complete: boolean = false;
6 |
7 | constructor() { }
8 | }
--------------------------------------------------------------------------------
/angular2-basic-todolist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Angular 2 Basic Project
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 | Loading...
25 |
26 |
27 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular2-basic",
3 | "version": "0.0.1",
4 | "scripts": {
5 | "start": "concurrently \"tsc -w\" \"lite-server\" ",
6 | "lite": "lite-server",
7 | "postinstall": "typings install",
8 | "tsc": "tsc",
9 | "tsc:w": "tsc -w",
10 | "typings": "typings"
11 | },
12 | "license": "MIT",
13 | "dependencies": {
14 | "@angular/common": "2.0.0",
15 | "@angular/compiler": "2.0.0",
16 | "@angular/core": "2.0.0",
17 | "@angular/forms": "2.0.0",
18 | "@angular/http": "2.0.0",
19 | "@angular/platform-browser": "2.0.0",
20 | "@angular/platform-browser-dynamic": "2.0.0",
21 | "@angular/router": "3.0.0",
22 | "@angular/upgrade": "2.0.0",
23 |
24 | "systemjs": "0.19.27",
25 | "core-js": "^2.4.1",
26 | "reflect-metadata": "^0.1.3",
27 | "rxjs": "5.0.0-beta.12",
28 | "zone.js": "^0.6.23",
29 | "angular2-in-memory-web-api": "0.0.20",
30 | "bootstrap": "^3.3.6"
31 | },
32 | "devDependencies": {
33 | "concurrently": "^2.2.0",
34 | "lite-server": "^2.2.2",
35 | "typescript": "^2.0.2",
36 | "typings": "^1.3.3"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/styles.css:
--------------------------------------------------------------------------------
1 | /* Master Styles */
2 | h1 {
3 | color: #369;
4 | font-size: 250%;
5 | }
6 | h2, h3 {
7 | color: #444;
8 | font-weight: lighter;
9 | }
10 |
11 | .app-root-loader{
12 | text-align: center;
13 | padding: 30px;
14 | }
15 |
16 | body {
17 | font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
18 | background: #f5f5f5;
19 | color: #4d4d4d;
20 | min-width: 230px;
21 | max-width: 550px;
22 | margin: 0 auto;
23 | -webkit-font-smoothing: antialiased;
24 | -moz-osx-font-smoothing: grayscale;
25 | font-weight: 300;
26 | }
--------------------------------------------------------------------------------
/angular2-basic-todolist/systemjs.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * System configuration for Angular 2 samples
3 | * Adjust as necessary for your application needs.
4 | */
5 | (function(global) {
6 | // map tells the System loader where to look for things
7 | var map = {
8 | 'app': 'build', // 'dist',
9 | '@angular': 'node_modules/@angular',
10 | 'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
11 | 'rxjs': 'node_modules/rxjs'
12 | };
13 | // packages tells the System loader how to load when no filename and/or no extension
14 | var packages = {
15 | 'app': { main: 'main.js', defaultExtension: 'js' },
16 | 'rxjs': { defaultExtension: 'js' },
17 | 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
18 | };
19 | var ngPackageNames = [
20 | 'common',
21 | 'compiler',
22 | 'core',
23 | 'forms',
24 | 'http',
25 | 'platform-browser',
26 | 'platform-browser-dynamic',
27 | 'router'
28 | ];
29 | // Individual files (~300 requests):
30 | function packIndex(pkgName) {
31 | packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
32 | }
33 | // Bundled (~40 requests):
34 | function packUmd(pkgName) {
35 | packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
36 | }
37 | // Most environments should use UMD; some (Karma) need the individual index files
38 | var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
39 | // Add package entries for angular packages
40 | ngPackageNames.forEach(setPackageConfig);
41 | var config = {
42 | map: map,
43 | packages: packages
44 | };
45 | System.config(config);
46 | })(this);
47 |
--------------------------------------------------------------------------------
/angular2-basic-todolist/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "removeComments": false,
10 | "noImplicitAny": false,
11 | "outDir": "./build/"
12 | }
13 | }
--------------------------------------------------------------------------------
/angular2-basic-todolist/typings.json:
--------------------------------------------------------------------------------
1 | {
2 | "globalDependencies": {
3 | "core-js": "registry:dt/core-js#0.0.0+20160725163759",
4 | "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
5 | "node": "registry:dt/node#6.0.0+20160831021119"
6 | }
7 | }
--------------------------------------------------------------------------------
/angular2-forms-tutorial/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | dist
3 | node_modules
4 | typings
5 |
6 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Mavlarn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/README.md:
--------------------------------------------------------------------------------
1 | # angular2-forms-tutorial
2 | A example project for tutorial.
3 |
4 | ## How to use.
5 | Clone the repository, install the dependency and run:
6 | ```
7 | git clone https://github.com/Mavlarn/angular2-forms-tutorial
8 | cd angular2-forms-tutorial
9 | npm install
10 | npm start
11 | ```
12 |
13 | ## tags ##
14 | 该项目包含几个有关Angular2表单的实例,分别用下面的tag打了标签:
15 | * template-driven
16 | * model-driven
17 |
18 | 可以使用下面的方法获取相关实例的代码:
19 | ```
20 | git checkout template-driven
21 | ```
22 |
23 | ## 在线教程 ##
24 | [Angular2表单-模板驱动的表单(Template-Driven Forms)](http://codin.im/2016/09/26/angular2-form-template-driven/)
25 | [Angular2表单-模型驱动的表单(Model-Driven Forms)](http://codin.im/2016/09/29/angular2-form-model-driven/)
26 | [Angular2表单-自定义验证器](http://codin.im/2016/10/08/angular2-form-custom-validator/)
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/app.component.css:
--------------------------------------------------------------------------------
1 | header section {
2 | display: inline-block;
3 | width: 60%;
4 | }
5 | header nav {
6 | width: 40%;
7 | float: right;
8 | margin-top: 20px;
9 | }
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | First Angular 2 App
4 |
5 |
11 |
12 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'root-app',
5 | templateUrl: 'app/app.component.html',
6 | styleUrls: ['app/app.component.css']
7 | })
8 |
9 | export class AppComponent {
10 | }
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { RouterModule } from '@angular/router';
4 | import { FormsModule } from '@angular/forms';
5 | import { ReactiveFormsModule } from '@angular/forms';
6 |
7 | import 'rxjs/add/operator/debounceTime';
8 | import 'rxjs/add/operator/distinctUntilChanged';
9 |
10 | import { AppComponent } from './app.component';
11 | import { TemplateFormsComponent } from './template-forms/template-forms.component';
12 | import { ReactiveFormsComponent } from './reactive-forms/reactive-forms.component';
13 | import { MobileValidator } from './validators/mobile.validator';
14 | import { routes } from './app.routes';
15 |
16 | @NgModule({
17 | imports: [BrowserModule, FormsModule, ReactiveFormsModule, RouterModule.forRoot(routes)],
18 | declarations: [AppComponent, TemplateFormsComponent, ReactiveFormsComponent, MobileValidator],
19 | bootstrap: [AppComponent]
20 | })
21 | export class AppModule {}
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/app.routes.ts:
--------------------------------------------------------------------------------
1 | import { Routes } from '@angular/router';
2 |
3 | import { TemplateFormsRoutes } from './template-forms/template-forms.routes';
4 | import { ReactiveFormsRoutes } from './reactive-forms/reactive-forms.routes';
5 |
6 | export const routes: Routes = [
7 | {
8 | path: '',
9 | redirectTo: '/template-forms',
10 | pathMatch: 'full'
11 | },
12 | ...TemplateFormsRoutes,
13 | ...ReactiveFormsRoutes
14 | ];
15 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
6 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/reactive-forms/reactive-forms.component.css:
--------------------------------------------------------------------------------
1 |
2 | .ng-valid[required], .ng-valid.required {
3 | border-left: 5px solid #42A948; /* green */
4 | }
5 |
6 | .ng-invalid:not(form).ng-invalid:not(fieldset) {
7 | border-left: 5px solid #a94442; /* red */
8 | }
9 |
10 | .error-msg {
11 | color: red;
12 | }
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/reactive-forms/reactive-forms.component.html:
--------------------------------------------------------------------------------
1 | 个人信息 (更新个人信息,模型驱动表单)
2 |
3 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/reactive-forms/reactive-forms.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';
3 |
4 | import { validateMobile } from '../validators/mobile.validator';
5 |
6 | @Component({
7 | selector: 'reactive-form',
8 | templateUrl: 'app/reactive-forms/reactive-forms.component.html',
9 | styleUrls: ['app/reactive-forms/reactive-forms.component.css']
10 | })
11 | export class ReactiveFormsComponent implements OnInit {
12 | userForm: FormGroup;
13 | msg: String;
14 | changeMsg: any;
15 |
16 | constructor(private formBuilder: FormBuilder) {}
17 |
18 | ngOnInit() {
19 | this.userForm = this.formBuilder.group({
20 | name: ['张三', [Validators.required, Validators.minLength(3)]],
21 | mobile: [13800138001, [Validators.required, Validators.minLength(11), Validators.maxLength(11), validateMobile]],
22 | address: this.formBuilder.group({
23 | city: ['北京', Validators.required],
24 | street: ['朝阳望京...', Validators.required]
25 | })
26 | });
27 | const addr$ = this.userForm.controls['address'];
28 | const city$ = addr$.controls['city'];
29 | const street$ = addr$.controls['street'];
30 |
31 | city$.valueChanges.debounceTime(1000).distinctUntilChanged().subscribe(cityValue => {
32 | this.msg = cityValue + ' 欢迎你!';
33 | street$.setValue(cityValue);
34 | });
35 |
36 | this.userForm.valueChanges.subscribe(x => this.changeMsg = { event: 'Form DATA CHANGED', object: x });
37 | }
38 |
39 | logForm(NgForm) {
40 | if (this.userForm.invalid) {
41 | this.msg = 'validation errors!';
42 | } else {
43 | this.msg = null;
44 | }
45 | console.log(this.userForm.value);
46 | }
47 |
48 | reset() {
49 | this.userForm.reset();
50 | }
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/reactive-forms/reactive-forms.routes.ts:
--------------------------------------------------------------------------------
1 | import { Route } from '@angular/router';
2 |
3 | import { ReactiveFormsComponent } from './reactive-forms.component';
4 |
5 | export const ReactiveFormsRoutes: Route[] = [
6 | {
7 | path: 'reactive-forms',
8 | component: ReactiveFormsComponent
9 | }
10 | ];
11 |
12 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/template-forms/template-forms.component.css:
--------------------------------------------------------------------------------
1 |
2 | .ng-valid[required], .ng-valid.required {
3 | border-left: 5px solid #42A948; /* green */
4 | }
5 |
6 | .ng-invalid:not(form).ng-invalid:not(fieldset) {
7 | border-left: 5px solid #a94442; /* red */
8 | }
9 |
10 | .error-msg {
11 | color: red;
12 | }
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/template-forms/template-forms.component.html:
--------------------------------------------------------------------------------
1 | 个人信息 (更新个人信息, 模板驱动表单)
2 |
3 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/template-forms/template-forms.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import {NgForm} from '@angular/forms';
3 |
4 | import { MobileValidator } from '../validators/mobile.validator';
5 |
6 | @Component({
7 | selector: 'template-form',
8 | templateUrl: 'app/template-forms/template-forms.component.html',
9 | styleUrls: ['app/template-forms/template-forms.component.css']
10 | })
11 | export class TemplateFormsComponent {
12 | user: any;
13 | active: Boolean = true;
14 | errorMsg: String;
15 | nameErrorMsg: String;
16 | constructor() {
17 | this.user = {
18 | name: '张三',
19 | mobile: 13800138001,
20 | address: {
21 | city: '北京',
22 | street: '朝阳望京...'
23 | }
24 | };
25 | }
26 | logForm(theForm: NgForm) {
27 | if (theForm.invalid) {
28 | this.errorMsg = 'validation errors!';
29 | if (theForm.controls['name'].errors) {
30 | this.nameErrorMsg = 'name error:' + JSON.stringify(theForm.controls['name'].errors);
31 | } else {
32 | this.nameErrorMsg = null;
33 | }
34 | } else {
35 | this.errorMsg = null;
36 | this.nameErrorMsg = null;
37 | }
38 | console.log(theForm.value);
39 | }
40 |
41 | create() {
42 | this.user = {
43 | address: {}
44 | };
45 | this.active = false;
46 | setTimeout(() => this.active = true, 0);
47 | return false;
48 | }
49 | reset(theForm: NgForm) {
50 | theForm.reset();
51 | return false;
52 | }
53 | diagnostic(model) {
54 | console.log(JSON.stringify(model));
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/template-forms/template-forms.routes.ts:
--------------------------------------------------------------------------------
1 | import { Route } from '@angular/router';
2 |
3 | import { TemplateFormsComponent } from './template-forms.component';
4 |
5 | export const TemplateFormsRoutes: Route[] = [
6 | {
7 | path: 'template-forms',
8 | component: TemplateFormsComponent
9 | }
10 | ];
11 |
12 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/app/validators/mobile.validator.ts:
--------------------------------------------------------------------------------
1 | import { FormControl, NG_VALIDATORS } from '@angular/forms';
2 | import { Directive } from '@angular/core';
3 |
4 | export function validateMobile(c: FormControl) {
5 | let MOBILE_REGEXP = /^1[0-9]{10,10}$/;
6 |
7 | return MOBILE_REGEXP.test(c.value) ? null : {
8 | validateMobile: {valid: false}
9 | }
10 | }
11 |
12 | @Directive({
13 | selector: '[validateMobile][ngModel]',
14 | providers: [
15 | { provide: NG_VALIDATORS, useValue: validateMobile, multi: true }
16 | ]
17 | })
18 | export class MobileValidator {}
19 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Angular 2 Template Driven Forms
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 | Loading...
25 |
26 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular2-template-driven-forms",
3 | "version": "0.0.1",
4 | "scripts": {
5 | "start": "concurrently \"tsc -w\" \"lite-server\" ",
6 | "lite": "lite-server",
7 | "postinstall": "typings install",
8 | "tsc": "tsc",
9 | "tsc:w": "tsc -w",
10 | "typings": "typings"
11 | },
12 | "license": "MIT",
13 | "dependencies": {
14 | "@angular/common": "2.0.0",
15 | "@angular/compiler": "2.0.0",
16 | "@angular/core": "2.0.0",
17 | "@angular/forms": "2.0.0",
18 | "@angular/http": "2.0.0",
19 | "@angular/platform-browser": "2.0.0",
20 | "@angular/platform-browser-dynamic": "2.0.0",
21 | "@angular/router": "3.0.0",
22 | "@angular/upgrade": "2.0.0",
23 |
24 | "systemjs": "0.19.27",
25 | "core-js": "^2.4.1",
26 | "reflect-metadata": "^0.1.3",
27 | "rxjs": "5.0.0-beta.12",
28 | "zone.js": "^0.6.23",
29 | "angular2-in-memory-web-api": "0.0.20",
30 | "bootstrap": "^3.3.6"
31 | },
32 | "devDependencies": {
33 | "concurrently": "^2.2.0",
34 | "lite-server": "^2.2.2",
35 | "typescript": "^2.0.2",
36 | "typings": "^1.3.3"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/styles.css:
--------------------------------------------------------------------------------
1 | /* Master Styles */
2 | h1 {
3 | color: #369;
4 | font-size: 250%;
5 | }
6 | h2, h3 {
7 | color: #444;
8 | font-weight: lighter;
9 | }
10 | body {
11 | margin: 2em;
12 | width: 500px;
13 | margin-left: auto;
14 | margin-right: auto;
15 | }
16 | body, input[text], button {
17 | color: #888;
18 | }
19 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/systemjs.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * System configuration for Angular 2 samples
3 | * Adjust as necessary for your application needs.
4 | */
5 | (function(global) {
6 | // map tells the System loader where to look for things
7 | var map = {
8 | 'app': 'build', // 'dist',
9 | '@angular': 'node_modules/@angular',
10 | 'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
11 | 'rxjs': 'node_modules/rxjs'
12 | };
13 | // packages tells the System loader how to load when no filename and/or no extension
14 | var packages = {
15 | 'app': { main: 'main.js', defaultExtension: 'js' },
16 | 'rxjs': { defaultExtension: 'js' },
17 | 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
18 | };
19 | var ngPackageNames = [
20 | 'common',
21 | 'compiler',
22 | 'core',
23 | 'forms',
24 | 'http',
25 | 'platform-browser',
26 | 'platform-browser-dynamic',
27 | 'router'
28 | ];
29 | // Individual files (~300 requests):
30 | function packIndex(pkgName) {
31 | packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
32 | }
33 | // Bundled (~40 requests):
34 | function packUmd(pkgName) {
35 | packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
36 | }
37 | // Most environments should use UMD; some (Karma) need the individual index files
38 | var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
39 | // Add package entries for angular packages
40 | ngPackageNames.forEach(setPackageConfig);
41 | var config = {
42 | map: map,
43 | packages: packages
44 | };
45 | System.config(config);
46 | })(this);
47 |
--------------------------------------------------------------------------------
/angular2-forms-tutorial/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "removeComments": false,
10 | "noImplicitAny": false,
11 | "outDir": "./build/"
12 | }
13 | }
--------------------------------------------------------------------------------
/angular2-forms-tutorial/typings.json:
--------------------------------------------------------------------------------
1 | {
2 | "globalDependencies": {
3 | "core-js": "registry:dt/core-js#0.0.0+20160725163759",
4 | "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
5 | "node": "registry:dt/node#6.0.0+20160831021119"
6 | }
7 | }
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | dist
3 | node_modules
4 | typings
5 | *.log
6 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "./node_modules/typescript/lib"
3 | }
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Mavlarn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Angular2路由教程2-使用Guard和Resolve进行验证和权限控制
3 | 教程 [Angular2路由教程2-使用Guard和Resolve进行验证和权限控制](http://codin.im/2016/11/12/angular2-route-2-guard-resolve/) 的项目源代码。
4 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/app.component.css:
--------------------------------------------------------------------------------
1 |
2 | h1 {
3 | width: 100%;
4 | font-size: 100px;
5 | font-weight: 100;
6 | text-align: center;
7 | color: rgba(175, 47, 47, 0.15);
8 | -webkit-text-rendering: optimizeLegibility;
9 | -moz-text-rendering: optimizeLegibility;
10 | text-rendering: optimizeLegibility;
11 | }
12 |
13 | footer {
14 | position: fixed;
15 | bottom: 30px;
16 | right: 50px;
17 | }
18 | footer .home {
19 | border-radius: 3px;
20 | background-color: lightgray;
21 | padding: 5px 15px;
22 | text-decoration: none;
23 | color: gray;
24 | }
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 | Todos
3 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'root-app',
5 | templateUrl: 'app/app.component.html',
6 | styleUrls: ['app/app.component.css']
7 | })
8 |
9 | export class AppComponent {
10 | }
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { RouterModule } from '@angular/router';
4 | import { FormsModule } from '@angular/forms';
5 |
6 | import { AppComponent } from './app.component';
7 | import { HomeComponent } from './home/home.component';
8 | import { TodoModule } from './todo/todo.module';
9 | import { routes } from './app.routes';
10 |
11 | import { AuthService } from './services/auth.service';
12 |
13 | @NgModule({
14 | imports: [BrowserModule, FormsModule, RouterModule.forRoot(routes), TodoModule],
15 | declarations: [AppComponent, HomeComponent],
16 | bootstrap: [AppComponent],
17 | providers: [AuthService]
18 | })
19 | export class AppModule {}
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/app.routes.ts:
--------------------------------------------------------------------------------
1 | import { Routes } from '@angular/router';
2 |
3 | import { HomeComponent } from './home/home.component';
4 | import { TodoRoutes } from './todo/todo.routes';
5 |
6 | export const routes: Routes = [
7 | {
8 | path: '',
9 | redirectTo: '/home',
10 | pathMatch: 'full'
11 | },
12 | {
13 | path: 'home',
14 | component: HomeComponent
15 | },
16 | ...TodoRoutes
17 | ];
18 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/home/home.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mavlarn/angular2-tutorial/6fb614e815700cdd055f0558845852fa7e43b797/angular2-routes-guards-resolve/app/home/home.component.css
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/home/home.component.html:
--------------------------------------------------------------------------------
1 | 欢迎
2 |
3 | 这是一个主页,你不需要登录也能看到。
4 |
5 |
6 |
7 |
这是管理员看到的页面。
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/home/home.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { Router } from '@angular/router';
3 |
4 | import { AuthService } from '../services/auth.service';
5 | @Component({
6 | selector: 'home',
7 | templateUrl: 'app/home/home.component.html',
8 | styleUrls: ['app/home/home.component.css']
9 | })
10 | export class HomeComponent {
11 |
12 | constructor(private authService: AuthService, private router: Router) {
13 |
14 | }
15 | isLoggedin() {
16 | return this.authService.isLogdedin();
17 | }
18 | login(role: string) {
19 | return this.authService.login(role).subscribe(() => {
20 | alert('login successfully as:' + role)
21 | if (role === 'CUSTOMER') {
22 | this.router.navigate(['/todo/list'])
23 | }
24 | });
25 | }
26 | hasRole(role: string): boolean {
27 | return this.authService.hasRole(role);
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
6 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/services/account.ts:
--------------------------------------------------------------------------------
1 | export class Account {
2 | id: number
3 | name: string
4 | roles: string[]
5 | }
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/services/auth.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | import { Account } from './account';
4 |
5 | import { Observable } from 'rxjs/Observable';
6 | import 'rxjs/add/observable/of';
7 |
8 | @Injectable()
9 | export class AuthService {
10 | account: Account;
11 |
12 | // simulation to login.
13 | login(role: string): Observable {
14 | let account = new Account();
15 | account.id = 11;
16 | account.name = 'super man';
17 | account.roles = [role];
18 | this.account = account;
19 | return Observable.of(account);
20 | }
21 | getAccount(): Account {
22 | return this.account;
23 | }
24 | isLogdedin(): boolean {
25 | return this.account && this.account.id != null;
26 | }
27 | hasRole(role: string): boolean {
28 | return this.account && this.account.roles.includes(role);
29 | }
30 | }
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/detail/detail.component.css:
--------------------------------------------------------------------------------
1 |
2 | .form-group label {
3 | display: inline-block;
4 | width: 100px;
5 | }
6 | .form-group p {
7 | display: inline-block;
8 | }
9 | a {
10 | border: solid 1px gray;
11 | border-radius: 3px;
12 | padding: 5px 20px;
13 | text-decoration: none;
14 | color: gray;
15 | cursor: pointer;
16 | }
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/detail/detail.component.html:
--------------------------------------------------------------------------------
1 | 任务详情
2 |
3 |
25 | 返回
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/detail/detail.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { ActivatedRoute, Router, Params } from '@angular/router';
3 |
4 | import { Todo } from '../todo';
5 | import { TodoService } from '../todo.service';
6 |
7 | @Component({
8 | selector: 'todo-detail',
9 | templateUrl: 'app/todo/detail/detail.component.html',
10 | styleUrls: ['app/todo/detail/detail.component.css']
11 | })
12 | export class TodoDetailComponent implements OnInit {
13 | selectedTodo: Todo;
14 | constructor(private route: ActivatedRoute,
15 | private router: Router,
16 | private todoService: TodoService) {}
17 |
18 | ngOnInit() {
19 | let todoId = +this.route.snapshot.params['id'];
20 | this.selectedTodo = this.todoService.getTodoById(todoId);
21 | if (!this.selectedTodo) {
22 | this.router.navigate(['/todo/list']);
23 | }
24 | }
25 | goBack() {
26 | window.history.back();
27 | }
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/item/item.component.css:
--------------------------------------------------------------------------------
1 |
2 | .todo-item .toggle {
3 | text-align: center;
4 | width: 40px;
5 | height: 40px;
6 | position: absolute;
7 | top: 0;
8 | bottom: 0;
9 | margin: auto 0;
10 | border: none; /* Mobile Safari */
11 | -webkit-appearance: none;
12 | appearance: none;
13 | }
14 |
15 | .todo-item .toggle:after {
16 | content: url('data:image/svg+xml;utf8,');
17 | }
18 |
19 | .todo-item .toggle:checked:after {
20 | content: url('data:image/svg+xml;utf8,');
21 | }
22 |
23 | .todo-item label {
24 | word-break: break-all;
25 | padding: 15px 60px 15px 15px;
26 | margin-left: 45px;
27 | display: block;
28 | line-height: 1.2;
29 | transition: color 0.4s;
30 | }
31 | .completed {
32 | background: lightyellow;
33 | }
34 | .todo-item.completed label {
35 | color: #d9d9d9;
36 | text-decoration: line-through;
37 | }
38 |
39 | .todo-item .destroy {
40 | display: none;
41 | position: absolute;
42 | top: 0;
43 | right: 10px;
44 | bottom: 0;
45 | width: 40px;
46 | height: 40px;
47 | margin: auto 0;
48 | font-size: 30px;
49 | color: #cc9a9a;
50 | margin-bottom: 11px;
51 | transition: color 0.2s ease-out;
52 | background: none;
53 | border: none;
54 | }
55 |
56 | .todo-item .destroy:hover {
57 | color: #af5b5e;
58 | }
59 |
60 | .todo-item .destroy:after {
61 | content: '×';
62 | }
63 |
64 | .todo-item:hover .destroy {
65 | display: block;
66 | }
67 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/item/item.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/item/item.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, ViewEncapsulation } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { Todo } from '../todo';
4 | import { TodoService } from '../todo.service';
5 |
6 | @Component({
7 | selector: 'todo-item',
8 | templateUrl: 'app/todo/item/item.component.html',
9 | styles: ['.completed { background: lightgreen; }'],
10 | styleUrls: ['app/todo/item/item.component.css'],
11 | encapsulation: ViewEncapsulation.Native
12 | })
13 | export class TodoItemComponent {
14 | @Input() todo: Todo;
15 |
16 | constructor(private todoService: TodoService, private router: Router) {
17 | }
18 |
19 | gotoDetail(todo) {
20 | this.router.navigate(['/todo/detail', todo.id]);
21 | }
22 |
23 | toggleTodoComplete(todo) {
24 | this.todoService.toggleTodoComplete(todo);
25 | }
26 | removeTodo(todo) {
27 | this.todoService.deleteTodoById(todo.id);
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/list/list.component.css:
--------------------------------------------------------------------------------
1 |
2 | button {
3 | margin: 0;
4 | padding: 0;
5 | border: 0;
6 | background: none;
7 | font-size: 100%;
8 | vertical-align: baseline;
9 | font-family: inherit;
10 | font-weight: inherit;
11 | color: inherit;
12 | -webkit-appearance: none;
13 | appearance: none;
14 | -webkit-font-smoothing: antialiased;
15 | -moz-osx-font-smoothing: grayscale;
16 | }
17 |
18 | :focus {
19 | outline: 0;
20 | }
21 |
22 | .hidden {
23 | display: none;
24 | }
25 |
26 | .todoapp {
27 | background: #fff;
28 | margin: 50px 0 40px 0;
29 | position: relative;
30 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
31 | 0 25px 50px 0 rgba(0, 0, 0, 0.1);
32 | }
33 |
34 | .todoapp input::-webkit-input-placeholder {
35 | font-style: italic;
36 | font-weight: 300;
37 | color: #e6e6e6;
38 | }
39 |
40 | .todoapp input::-moz-placeholder {
41 | font-style: italic;
42 | font-weight: 300;
43 | color: #e6e6e6;
44 | }
45 |
46 | .todoapp input::input-placeholder {
47 | font-style: italic;
48 | font-weight: 300;
49 | color: #e6e6e6;
50 | }
51 |
52 | .new-todo,
53 | .edit {
54 | position: relative;
55 | margin: 0;
56 | width: 100%;
57 | font-size: 24px;
58 | font-family: inherit;
59 | font-weight: inherit;
60 | line-height: 1.4em;
61 | border: 0;
62 | color: inherit;
63 | padding: 6px;
64 | border: 1px solid #999;
65 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
66 | box-sizing: border-box;
67 | -webkit-font-smoothing: antialiased;
68 | -moz-osx-font-smoothing: grayscale;
69 | }
70 |
71 | .new-todo {
72 | padding: 16px 16px 16px 60px;
73 | border: none;
74 | background: rgba(0, 0, 0, 0.003);
75 | box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
76 | }
77 |
78 | .main {
79 | position: relative;
80 | z-index: 2;
81 | border-top: 1px solid #e6e6e6;
82 | }
83 |
84 | .todo-list {
85 | margin: 0;
86 | padding: 0;
87 | list-style: none;
88 | }
89 |
90 | .todo-list todo-item {
91 | position: relative;
92 | font-size: 24px;
93 | border-bottom: 1px solid #ededed;
94 | display: list-item;
95 | }
96 |
97 | .todo-list todo-item:last-child {
98 | border-bottom: none;
99 | }
100 |
101 | .footer {
102 | color: #777;
103 | padding: 10px 15px;
104 | height: 20px;
105 | text-align: center;
106 | border-top: 1px solid #e6e6e6;
107 | }
108 |
109 | .footer:before {
110 | content: '';
111 | position: absolute;
112 | right: 0;
113 | bottom: 0;
114 | left: 0;
115 | height: 50px;
116 | overflow: hidden;
117 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
118 | 0 8px 0 -3px #f6f6f6,
119 | 0 9px 1px -3px rgba(0, 0, 0, 0.2),
120 | 0 16px 0 -6px #f6f6f6,
121 | 0 17px 2px -6px rgba(0, 0, 0, 0.2);
122 | }
123 |
124 | .todo-count {
125 | float: left;
126 | text-align: left;
127 | }
128 |
129 | .todo-count strong {
130 | font-weight: 300;
131 | }
132 |
133 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/list/list.component.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/list/list.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { ActivatedRoute } from '@angular/router';
4 | import { Todo } from '../todo';
5 | import { TodoService } from '../todo.service';
6 |
7 | @Component({
8 | selector: 'todo-list',
9 | templateUrl: 'app/todo/list/list.component.html',
10 | styleUrls: ['app/todo//list/list.component.css']
11 | })
12 | export class TodoListComponent {
13 | newTodo: Todo = new Todo();
14 | todos: Todo[];
15 | title: string;
16 |
17 | constructor(private todoService: TodoService, private route: ActivatedRoute) {
18 | this.todos = this.route.snapshot.data['todos'];
19 | this.title = this.route.data['title'];
20 | }
21 |
22 | addTodo() {
23 | if (!this.newTodo.title.trim()) {
24 | return;
25 | }
26 | this.todoService.addTodo(this.newTodo);
27 | this.newTodo = new Todo();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/todo.guards.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { CanActivate, CanActivateChild, CanDeactivate, Router,
3 | ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
4 |
5 | import { AuthService } from '../services/auth.service';
6 | import { TodoDetailComponent } from './detail/detail.component';
7 |
8 | @Injectable()
9 | export class MyTodoGuard implements CanActivate, CanActivateChild {
10 |
11 | constructor(private authService: AuthService, private router: Router) {}
12 |
13 | canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
14 | console.log('can activate: ', next.url[0].path);
15 | let requiredRole = next.data['role'];
16 | console.log('Require role: ', requiredRole);
17 | if (!this.authService.isLogdedin()) {
18 | alert('You need to login!');
19 | this.router.navigate(['/home']);
20 | return false;
21 | }
22 | if (requiredRole == null || this.authService.hasRole(requiredRole)) {
23 | return true;
24 | }
25 | return false;
26 | }
27 |
28 | canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
29 | console.log('can activate child: ', childRoute.url[0].path);
30 | return this.canActivate(childRoute, state);
31 | }
32 | }
33 |
34 | @Injectable()
35 | export class CanLeaveTodoDetailGuard implements CanDeactivate {
36 | canDeactivate(component: TodoDetailComponent, route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
37 | return confirm('Confirm?');
38 | }
39 | }
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/todo.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule } from '@angular/forms';
4 |
5 | import { TodoListComponent } from './list/list.component';
6 | import { TodoDetailComponent } from './detail/detail.component';
7 | import { TodoItemComponent } from './item/item.component';
8 | import { TodoService } from './todo.service';
9 | import { MyTodoResolver } from './todo.resolver';
10 | import { MyTodoGuard, CanLeaveTodoDetailGuard } from './todo.guards';
11 |
12 | @NgModule({
13 | imports: [CommonModule, FormsModule ],
14 | declarations: [TodoListComponent, TodoDetailComponent, TodoItemComponent],
15 | providers: [TodoService, MyTodoResolver, MyTodoGuard, CanLeaveTodoDetailGuard]
16 | })
17 | export class TodoModule {}
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/todo.resolver.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
3 |
4 | import { Todo } from './todo';
5 | import { TodoService } from './todo.service';
6 |
7 | @Injectable()
8 | export class MyTodoResolver implements Resolve {
9 |
10 | constructor(private todoService: TodoService) { }
11 |
12 | resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
13 | console.log('Get my todo list.');
14 | return this.todoService.getAllTodos();
15 | }
16 | }
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/todo.routes.ts:
--------------------------------------------------------------------------------
1 | import { Route } from '@angular/router';
2 |
3 | import { TodoListComponent } from './list/list.component';
4 | import { TodoDetailComponent } from './detail/detail.component';
5 |
6 | import { MyTodoGuard, CanLeaveTodoDetailGuard } from './todo.guards';
7 | import { MyTodoResolver } from './todo.resolver';
8 |
9 | export const TodoRoutes: Route[] = [
10 | {
11 | path: 'todo',
12 | data: {
13 | role: 'CUSTOMER',
14 | title: '任务'
15 | },
16 | canActivateChild: [MyTodoGuard],
17 | children: [
18 | {
19 | path: 'list',
20 | component: TodoListComponent,
21 | resolve: {
22 | todos: MyTodoResolver
23 | },
24 | data: {
25 | title: '列表'
26 | }
27 | },
28 | {
29 | path: 'detail/:id',
30 | component: TodoDetailComponent,
31 | canDeactivate: [ CanLeaveTodoDetailGuard ],
32 | data: {
33 | title: '详情'
34 | }
35 | }
36 | ]
37 | }
38 | ];
39 |
40 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/todo.service.ts:
--------------------------------------------------------------------------------
1 | import {Injectable} from '@angular/core';
2 | import {Todo} from './todo';
3 |
4 | import { Observable } from 'rxjs/Observable';
5 | import 'rxjs/add/observable/of';
6 | import 'rxjs/add/operator/delay';
7 |
8 | @Injectable()
9 | export class TodoService {
10 |
11 | // 为了生成一个自增的id,保存最后一个生成的id
12 | lastId: number = 0;
13 | todos: Todo[] = []; // 任务列表
14 |
15 | constructor() {}
16 |
17 | // 添加一个任务
18 | addTodo(todo: Todo): TodoService {
19 | if (!todo.id) {
20 | todo.id = ++this.lastId;
21 | }
22 | this.todos.push(todo);
23 | return this;
24 | }
25 |
26 | // 从任务列表里删除一个任务
27 | deleteTodoById(id: number): TodoService {
28 | this.todos = this.todos.filter(todo => todo.id !== id);
29 | return this;
30 | }
31 |
32 | // 更新一个任务
33 | updateTodoById(id: number, values: Object = {}): Todo {
34 | let todo = this.getTodoById(id);
35 | if (!todo) {
36 | return null;
37 | }
38 | Object.assign(todo, values);
39 | return todo;
40 | }
41 |
42 | getAllTodos(): Observable {
43 | let todo1 = new Todo();
44 | todo1.id = 1;
45 | todo1.title = 'test task 1';
46 | todo1.createdDate = new Date();
47 | todo1.complete = false;
48 | let todo2 = new Todo();
49 | todo2.id = 2;
50 | todo2.title = 'test task 2';
51 | todo2.createdDate = new Date();
52 | todo2.complete = false;
53 |
54 | this.todos = [todo1, todo2];
55 | return Observable.of(this.todos).delay(3000);
56 | }
57 |
58 | getTodoById(id: number): Todo {
59 | return this.todos.filter(todo => todo.id === id).pop();
60 | }
61 |
62 | // 标记一个任务为完成/未完成
63 | toggleTodoComplete(todo: Todo){
64 | let updatedTodo = this.updateTodoById(todo.id, {
65 | complete: !todo.complete
66 | });
67 | return updatedTodo;
68 | }
69 | }
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/app/todo/todo.ts:
--------------------------------------------------------------------------------
1 | export class Todo {
2 | id: number;
3 | title: string = '';
4 | createdDate: Date = new Date();
5 | complete: boolean = false;
6 |
7 | constructor() { }
8 | }
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Angular 2 Basic Project
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 | Loading...
25 |
26 |
27 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular2-basic",
3 | "version": "0.0.1",
4 | "scripts": {
5 | "start": "concurrently \"tsc -w\" \"lite-server\" ",
6 | "lite": "lite-server",
7 | "postinstall": "typings install",
8 | "tsc": "tsc",
9 | "tsc:w": "tsc -w",
10 | "typings": "typings"
11 | },
12 | "license": "MIT",
13 | "dependencies": {
14 | "@angular/common": "2.0.0",
15 | "@angular/compiler": "2.0.0",
16 | "@angular/core": "2.0.0",
17 | "@angular/forms": "2.0.0",
18 | "@angular/http": "2.0.0",
19 | "@angular/platform-browser": "2.0.0",
20 | "@angular/platform-browser-dynamic": "2.0.0",
21 | "@angular/router": "3.0.0",
22 | "@angular/upgrade": "2.0.0",
23 |
24 | "systemjs": "0.19.27",
25 | "core-js": "^2.4.1",
26 | "reflect-metadata": "^0.1.3",
27 | "rxjs": "5.0.0-beta.12",
28 | "zone.js": "^0.6.23",
29 | "angular2-in-memory-web-api": "0.0.20",
30 | "bootstrap": "^3.3.6"
31 | },
32 | "devDependencies": {
33 | "concurrently": "^2.2.0",
34 | "lite-server": "^2.2.2",
35 | "typescript": "^2.0.2",
36 | "typings": "^1.3.3"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/styles.css:
--------------------------------------------------------------------------------
1 | /* Master Styles */
2 | h1 {
3 | color: #369;
4 | font-size: 250%;
5 | }
6 | h2, h3 {
7 | color: #444;
8 | font-weight: lighter;
9 | }
10 |
11 | .app-root-loader{
12 | text-align: center;
13 | padding: 30px;
14 | }
15 |
16 | body {
17 | font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
18 | background: #f5f5f5;
19 | color: #4d4d4d;
20 | min-width: 230px;
21 | max-width: 550px;
22 | margin: 0 auto;
23 | -webkit-font-smoothing: antialiased;
24 | -moz-osx-font-smoothing: grayscale;
25 | font-weight: 300;
26 | }
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/systemjs.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * System configuration for Angular 2 samples
3 | * Adjust as necessary for your application needs.
4 | */
5 | (function(global) {
6 | // map tells the System loader where to look for things
7 | var map = {
8 | 'app': 'build', // 'dist',
9 | '@angular': 'node_modules/@angular',
10 | 'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
11 | 'rxjs': 'node_modules/rxjs'
12 | };
13 | // packages tells the System loader how to load when no filename and/or no extension
14 | var packages = {
15 | 'app': { main: 'main.js', defaultExtension: 'js' },
16 | 'rxjs': { defaultExtension: 'js' },
17 | 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
18 | };
19 | var ngPackageNames = [
20 | 'common',
21 | 'compiler',
22 | 'core',
23 | 'forms',
24 | 'http',
25 | 'platform-browser',
26 | 'platform-browser-dynamic',
27 | 'router'
28 | ];
29 | // Individual files (~300 requests):
30 | function packIndex(pkgName) {
31 | packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
32 | }
33 | // Bundled (~40 requests):
34 | function packUmd(pkgName) {
35 | packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
36 | }
37 | // Most environments should use UMD; some (Karma) need the individual index files
38 | var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
39 | // Add package entries for angular packages
40 | ngPackageNames.forEach(setPackageConfig);
41 | var config = {
42 | map: map,
43 | packages: packages
44 | };
45 | System.config(config);
46 | })(this);
47 |
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "removeComments": false,
10 | "noImplicitAny": false,
11 | "outDir": "./build/"
12 | }
13 | }
--------------------------------------------------------------------------------
/angular2-routes-guards-resolve/typings.json:
--------------------------------------------------------------------------------
1 | {
2 | "globalDependencies": {
3 | "core-js": "registry:dt/core-js#0.0.0+20160725163759",
4 | "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
5 | "node": "registry:dt/node#6.0.0+20160831021119"
6 | }
7 | }
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 |
7 | # dependencies
8 | /node_modules
9 | /bower_components
10 |
11 | # IDEs and editors
12 | /.idea
13 | /.vscode
14 | .project
15 | .classpath
16 | .c9/
17 | *.launch
18 | .settings/
19 |
20 | # misc
21 | /.sass-cache
22 | /connect.lock
23 | /coverage/*
24 | /libpeerconnection.log
25 | npm-debug.log
26 | testem.log
27 | /typings
28 |
29 | # e2e
30 | /e2e/*.js
31 | /e2e/*.map
32 |
33 | #System Files
34 | .DS_Store
35 | Thumbs.db
36 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/README.md:
--------------------------------------------------------------------------------
1 | # Angular2 Routes LazyModule
2 |
3 | Example of angular2 sub module and lazy module.
4 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/angular-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "project": {
3 | "version": "1.0.0-beta.22-1",
4 | "name": "angular2-routes-lazy-module"
5 | },
6 | "apps": [
7 | {
8 | "root": "src",
9 | "outDir": "dist",
10 | "assets": [
11 | "assets",
12 | "favicon.ico"
13 | ],
14 | "index": "index.html",
15 | "main": "main.ts",
16 | "test": "test.ts",
17 | "tsconfig": "tsconfig.json",
18 | "prefix": "app",
19 | "mobile": false,
20 | "styles": [
21 | "styles.css"
22 | ],
23 | "scripts": [],
24 | "environments": {
25 | "source": "environments/environment.ts",
26 | "dev": "environments/environment.ts",
27 | "prod": "environments/environment.prod.ts"
28 | }
29 | }
30 | ],
31 | "addons": [],
32 | "packages": [],
33 | "e2e": {
34 | "protractor": {
35 | "config": "./protractor.conf.js"
36 | }
37 | },
38 | "test": {
39 | "karma": {
40 | "config": "./karma.conf.js"
41 | }
42 | },
43 | "defaults": {
44 | "styleExt": "css",
45 | "prefixInterfaces": false,
46 | "inline": {
47 | "style": false,
48 | "template": false
49 | },
50 | "spec": {
51 | "class": false,
52 | "component": true,
53 | "directive": true,
54 | "module": false,
55 | "pipe": true,
56 | "service": true
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { Angular2RoutesLazyModulePage } from './app.po';
2 |
3 | describe('angular2-routes-lazy-module App', function() {
4 | let page: Angular2RoutesLazyModulePage;
5 |
6 | beforeEach(() => {
7 | page = new Angular2RoutesLazyModulePage();
8 | });
9 |
10 | it('should display message saying app works', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toEqual('app works!');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/e2e/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, element, by } from 'protractor';
2 |
3 | export class Angular2RoutesLazyModulePage {
4 | navigateTo() {
5 | return browser.get('/');
6 | }
7 |
8 | getParagraphText() {
9 | return element(by.css('app-root h1')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "declaration": false,
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "module": "commonjs",
8 | "moduleResolution": "node",
9 | "outDir": "../dist/out-tsc-e2e",
10 | "sourceMap": true,
11 | "target": "es5",
12 | "typeRoots": [
13 | "../node_modules/@types"
14 | ]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/0.13/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', 'angular-cli'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-remap-istanbul'),
12 | require('angular-cli/plugins/karma')
13 | ],
14 | files: [
15 | { pattern: './src/test.ts', watched: false }
16 | ],
17 | preprocessors: {
18 | './src/test.ts': ['angular-cli']
19 | },
20 | mime: {
21 | 'text/x-typescript': ['ts','tsx']
22 | },
23 | remapIstanbulReporter: {
24 | reports: {
25 | html: 'coverage',
26 | lcovonly: './coverage/coverage.lcov'
27 | }
28 | },
29 | angularCli: {
30 | config: './angular-cli.json',
31 | environment: 'dev'
32 | },
33 | reporters: config.angularCli && config.angularCli.codeCoverage
34 | ? ['progress', 'karma-remap-istanbul']
35 | : ['progress'],
36 | port: 9876,
37 | colors: true,
38 | logLevel: config.LOG_INFO,
39 | autoWatch: true,
40 | browsers: ['Chrome'],
41 | singleRun: false
42 | });
43 | };
44 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular2-routes-lazy-module",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "angular-cli": {},
6 | "scripts": {
7 | "start": "ng serve",
8 | "lint": "tslint \"src/**/*.ts\"",
9 | "test": "ng test",
10 | "pree2e": "webdriver-manager update",
11 | "e2e": "protractor"
12 | },
13 | "private": true,
14 | "dependencies": {
15 | "@angular/common": "2.2.1",
16 | "@angular/compiler": "2.2.1",
17 | "@angular/core": "2.2.1",
18 | "@angular/forms": "2.2.1",
19 | "@angular/http": "2.2.1",
20 | "@angular/platform-browser": "2.2.1",
21 | "@angular/platform-browser-dynamic": "2.2.1",
22 | "@angular/router": "3.1.1",
23 | "core-js": "^2.4.1",
24 | "rxjs": "5.0.0-rc.4",
25 | "ts-helpers": "^1.1.1",
26 | "zone.js": "^0.7.1"
27 | },
28 | "devDependencies": {
29 | "@angular/compiler-cli": "2.2.1",
30 | "@types/jasmine": "2.5.38",
31 | "@types/node": "^6.0.42",
32 | "angular-cli": "1.0.0-beta.22",
33 | "codelyzer": "~2.0.0-beta.1",
34 | "jasmine-core": "2.5.2",
35 | "jasmine-spec-reporter": "2.5.0",
36 | "karma": "1.2.0",
37 | "karma-chrome-launcher": "^2.0.0",
38 | "karma-cli": "^1.0.1",
39 | "karma-jasmine": "^1.0.2",
40 | "karma-remap-istanbul": "^0.2.1",
41 | "protractor": "4.0.9",
42 | "ts-node": "1.2.1",
43 | "tslint": "^4.0.2",
44 | "typescript": "~2.0.3",
45 | "webdriver-manager": "10.2.5"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // Protractor configuration file, see link for more information
2 | // https://github.com/angular/protractor/blob/master/docs/referenceConf.js
3 |
4 | /*global jasmine */
5 | var SpecReporter = require('jasmine-spec-reporter');
6 |
7 | exports.config = {
8 | allScriptsTimeout: 11000,
9 | specs: [
10 | './e2e/**/*.e2e-spec.ts'
11 | ],
12 | capabilities: {
13 | 'browserName': 'chrome'
14 | },
15 | directConnect: true,
16 | baseUrl: 'http://localhost:4200/',
17 | framework: 'jasmine',
18 | jasmineNodeOpts: {
19 | showColors: true,
20 | defaultTimeoutInterval: 30000,
21 | print: function() {}
22 | },
23 | useAllAngular2AppRoots: true,
24 | beforeLaunch: function() {
25 | require('ts-node').register({
26 | project: 'e2e'
27 | });
28 | },
29 | onPrepare: function() {
30 | jasmine.getEnv().addReporter(new SpecReporter());
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/app.component.css:
--------------------------------------------------------------------------------
1 |
2 | h1 {
3 | width: 100%;
4 | font-size: 100px;
5 | font-weight: 100;
6 | text-align: center;
7 | color: rgba(175, 47, 47, 0.15);
8 | -webkit-text-rendering: optimizeLegibility;
9 | -moz-text-rendering: optimizeLegibility;
10 | text-rendering: optimizeLegibility;
11 | }
12 |
13 | footer {
14 | position: fixed;
15 | bottom: 30px;
16 | right: 50px;
17 | }
18 | footer .home {
19 | border-radius: 3px;
20 | background-color: lightgray;
21 | padding: 5px 15px;
22 | text-decoration: none;
23 | color: gray;
24 | }
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 | Todos
3 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-root',
5 | templateUrl: './app.component.html',
6 | styleUrls: ['./app.component.css']
7 | })
8 |
9 | export class AppComponent {
10 | }
11 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 |
4 | import { AppComponent } from './app.component';
5 | import { HomeComponent } from './home/home.component';
6 |
7 | import { AppRoutingModule } from './app.routes';
8 |
9 | import { AuthService } from './services/auth.service';
10 |
11 | import { Observable } from 'rxjs/Observable';
12 |
13 | @NgModule({
14 | imports: [BrowserModule, AppRoutingModule],
15 | declarations: [AppComponent, HomeComponent],
16 | bootstrap: [AppComponent],
17 | providers: [AuthService]
18 | })
19 | export class AppModule {}
20 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/app.routes.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | import { HomeComponent } from './home/home.component';
5 |
6 | const routes: Routes = [
7 | { path: '', redirectTo: '/home', pathMatch: 'full' },
8 | { path: 'home', component: HomeComponent },
9 | { path: 'todo', loadChildren: 'app/todo/todo.module#TodoModule' },
10 | { path: 'lazy', loadChildren: 'app/lazy/lazy.module#LazyModule' }
11 | ];
12 |
13 | @NgModule({
14 | imports: [ RouterModule.forRoot(routes) ],
15 | exports: [ RouterModule ]
16 | })
17 | export class AppRoutingModule { }
18 |
19 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/home/home.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mavlarn/angular2-tutorial/6fb614e815700cdd055f0558845852fa7e43b797/angular2-routes-lazy-module-webpack/src/app/home/home.component.css
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/home/home.component.html:
--------------------------------------------------------------------------------
1 | 欢迎
2 |
3 | 这是一个主页,你不需要登录也能看到。
4 |
5 |
6 |
7 |
这是管理员看到的页面。
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/home/home.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { Router } from '@angular/router';
3 |
4 | import { Subscription } from 'rxjs/Subscription';
5 |
6 | import { AuthService } from '../services/auth.service';
7 |
8 | @Component({
9 | selector: 'home',
10 | templateUrl: './home.component.html',
11 | styleUrls: ['./home.component.css']
12 | })
13 | export class HomeComponent {
14 |
15 | constructor(private authService: AuthService, private router: Router) {
16 |
17 | }
18 | isLoggedin() {
19 | return this.authService.isLogdedin();
20 | }
21 | login(role: string) {
22 | return this.authService.login(role).subscribe(() => {
23 | alert('login successfully as:' + role)
24 | if (role === 'CUSTOMER') {
25 | this.router.navigate(['/todo/list'])
26 | }
27 | });
28 | }
29 | hasRole(role: string): boolean {
30 | return this.authService.hasRole(role);
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/index.ts:
--------------------------------------------------------------------------------
1 | export * from './app.component';
2 | export * from './app.module';
3 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/lazy/lazy.component.html:
--------------------------------------------------------------------------------
1 |
2 | LAZY works!
3 |
4 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/lazy/lazy.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mavlarn/angular2-tutorial/6fb614e815700cdd055f0558845852fa7e43b797/angular2-routes-lazy-module-webpack/src/app/lazy/lazy.component.scss
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/lazy/lazy.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 |
3 | import { TestBed, async } from '@angular/core/testing';
4 | import { LazyComponent } from './lazy.component';
5 |
6 | describe('Component: Lazy', () => {
7 | it('should create an instance', () => {
8 | let component = new LazyComponent();
9 | expect(component).toBeTruthy();
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/lazy/lazy.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'lazy-lazy',
5 | templateUrl: './lazy.component.html',
6 | styleUrls: ['./lazy.component.scss']
7 | })
8 | export class LazyComponent implements OnInit {
9 |
10 | constructor() { }
11 |
12 | ngOnInit() {
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/lazy/lazy.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from "@angular/core";
2 | import { CommonModule } from "@angular/common";
3 |
4 | import { LazyRoutingModule } from './lazy.routing.module';
5 | import { LazyComponent } from "./lazy.component";
6 |
7 |
8 | @NgModule({
9 | declarations: [ LazyComponent ],
10 | imports: [ CommonModule, LazyRoutingModule ]
11 | })
12 | export class LazyModule {}
13 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/lazy/lazy.routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | import { LazyComponent } from './lazy.component';
5 |
6 |
7 | const LAZY_ROUTES: Routes = [
8 | { path: '', component: LazyComponent }
9 | ];
10 |
11 | const lazyRouting = RouterModule.forChild(LAZY_ROUTES);
12 |
13 | @NgModule({
14 | imports: [ lazyRouting ],
15 | exports: [ RouterModule ]
16 | })
17 | export class LazyRoutingModule {}
18 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/services/account.ts:
--------------------------------------------------------------------------------
1 | export class Account {
2 | id: number
3 | name: string
4 | roles: string[]
5 | }
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/services/auth.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | import { Account } from './account';
4 |
5 | import { Observable } from 'rxjs/Observable';
6 | import 'rxjs/add/observable/of';
7 |
8 | @Injectable()
9 | export class AuthService {
10 | account: Account;
11 |
12 | constructor() {
13 | console.log('AuthService created.');
14 | }
15 |
16 | // simulation to login.
17 | login(role: string): Observable {
18 | let account = new Account();
19 | account.id = 11;
20 | account.name = 'super man';
21 | account.roles = [role];
22 | this.account = account;
23 | return Observable.of(account);
24 | }
25 | getAccount(): Account {
26 | return this.account;
27 | }
28 | isLogdedin(): boolean {
29 | return this.account && this.account.id != null;
30 | }
31 | hasRole(role: string): boolean {
32 | return this.account && this.account.roles.indexOf(role) >= 0;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/detail/detail.component.css:
--------------------------------------------------------------------------------
1 |
2 | .form-group label {
3 | display: inline-block;
4 | width: 100px;
5 | }
6 | .form-group p {
7 | display: inline-block;
8 | }
9 | a {
10 | border: solid 1px gray;
11 | border-radius: 3px;
12 | padding: 5px 20px;
13 | text-decoration: none;
14 | color: gray;
15 | cursor: pointer;
16 | }
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/detail/detail.component.html:
--------------------------------------------------------------------------------
1 | 任务详情
2 |
3 |
25 | 返回
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/detail/detail.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { ActivatedRoute, Router, Params } from '@angular/router';
3 |
4 | import { Todo } from '../todo';
5 | import { TodoService } from '../todo.service';
6 |
7 | @Component({
8 | selector: 'todo-detail',
9 | templateUrl: './detail.component.html',
10 | styleUrls: ['./detail.component.css']
11 | })
12 | export class TodoDetailComponent implements OnInit {
13 | selectedTodo: Todo;
14 | constructor(private route: ActivatedRoute,
15 | private router: Router,
16 | private todoService: TodoService) {}
17 |
18 | ngOnInit() {
19 | let todoId = +this.route.snapshot.params['id'];
20 | this.selectedTodo = this.todoService.getTodoById(todoId);
21 | if (!this.selectedTodo) {
22 | this.router.navigate(['/todo/list']);
23 | }
24 | }
25 | goBack() {
26 | window.history.back();
27 | }
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/item/item.component.css:
--------------------------------------------------------------------------------
1 |
2 | .todo-item .toggle {
3 | text-align: center;
4 | width: 40px;
5 | height: 40px;
6 | position: absolute;
7 | top: 0;
8 | bottom: 0;
9 | margin: auto 0;
10 | border: none; /* Mobile Safari */
11 | -webkit-appearance: none;
12 | appearance: none;
13 | }
14 |
15 | .todo-item .toggle:after {
16 | content: url('data:image/svg+xml;utf8,');
17 | }
18 |
19 | .todo-item .toggle:checked:after {
20 | content: url('data:image/svg+xml;utf8,');
21 | }
22 |
23 | .todo-item label {
24 | word-break: break-all;
25 | padding: 15px 60px 15px 15px;
26 | margin-left: 45px;
27 | display: block;
28 | line-height: 1.2;
29 | transition: color 0.4s;
30 | }
31 | .completed {
32 | background: lightyellow;
33 | }
34 | .todo-item.completed label {
35 | color: #d9d9d9;
36 | text-decoration: line-through;
37 | }
38 |
39 | .todo-item .destroy {
40 | display: none;
41 | position: absolute;
42 | top: 0;
43 | right: 10px;
44 | bottom: 0;
45 | width: 40px;
46 | height: 40px;
47 | margin: auto 0;
48 | font-size: 30px;
49 | color: #cc9a9a;
50 | margin-bottom: 11px;
51 | transition: color 0.2s ease-out;
52 | background: none;
53 | border: none;
54 | }
55 |
56 | .todo-item .destroy:hover {
57 | color: #af5b5e;
58 | }
59 |
60 | .todo-item .destroy:after {
61 | content: '×';
62 | }
63 |
64 | .todo-item:hover .destroy {
65 | display: block;
66 | }
67 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/item/item.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/item/item.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, ViewEncapsulation } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { Todo } from '../todo';
4 | import { TodoService } from '../todo.service';
5 |
6 | @Component({
7 | selector: 'todo-item',
8 | templateUrl: './item.component.html',
9 | // styles: ['.completed { background: lightgreen; }'],
10 | styleUrls: ['./item.component.css'],
11 | encapsulation: ViewEncapsulation.Native
12 | })
13 | export class TodoItemComponent {
14 | @Input() todo: Todo;
15 |
16 | constructor(private todoService: TodoService, private router: Router) {
17 | }
18 |
19 | gotoDetail(todo) {
20 | this.router.navigate(['/todo/detail', todo.id]);
21 | }
22 |
23 | toggleTodoComplete(todo) {
24 | this.todoService.toggleTodoComplete(todo);
25 | }
26 | removeTodo(todo) {
27 | this.todoService.deleteTodoById(todo.id);
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/list/list.component.css:
--------------------------------------------------------------------------------
1 |
2 | button {
3 | margin: 0;
4 | padding: 0;
5 | border: 0;
6 | background: none;
7 | font-size: 100%;
8 | vertical-align: baseline;
9 | font-family: inherit;
10 | font-weight: inherit;
11 | color: inherit;
12 | -webkit-appearance: none;
13 | appearance: none;
14 | -webkit-font-smoothing: antialiased;
15 | -moz-osx-font-smoothing: grayscale;
16 | }
17 |
18 | :focus {
19 | outline: 0;
20 | }
21 |
22 | .hidden {
23 | display: none;
24 | }
25 |
26 | .todoapp {
27 | background: #fff;
28 | margin: 50px 0 40px 0;
29 | position: relative;
30 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
31 | 0 25px 50px 0 rgba(0, 0, 0, 0.1);
32 | }
33 |
34 | .todoapp input::-webkit-input-placeholder {
35 | font-style: italic;
36 | font-weight: 300;
37 | color: #e6e6e6;
38 | }
39 |
40 | .todoapp input::-moz-placeholder {
41 | font-style: italic;
42 | font-weight: 300;
43 | color: #e6e6e6;
44 | }
45 |
46 | .todoapp input::input-placeholder {
47 | font-style: italic;
48 | font-weight: 300;
49 | color: #e6e6e6;
50 | }
51 |
52 | .new-todo,
53 | .edit {
54 | position: relative;
55 | margin: 0;
56 | width: 100%;
57 | font-size: 24px;
58 | font-family: inherit;
59 | font-weight: inherit;
60 | line-height: 1.4em;
61 | border: 0;
62 | color: inherit;
63 | padding: 6px;
64 | border: 1px solid #999;
65 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
66 | box-sizing: border-box;
67 | -webkit-font-smoothing: antialiased;
68 | -moz-osx-font-smoothing: grayscale;
69 | }
70 |
71 | .new-todo {
72 | padding: 16px 16px 16px 60px;
73 | border: none;
74 | background: rgba(0, 0, 0, 0.003);
75 | box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
76 | }
77 |
78 | .main {
79 | position: relative;
80 | z-index: 2;
81 | border-top: 1px solid #e6e6e6;
82 | }
83 |
84 | .todo-list {
85 | margin: 0;
86 | padding: 0;
87 | list-style: none;
88 | }
89 |
90 | .todo-list todo-item {
91 | position: relative;
92 | font-size: 24px;
93 | border-bottom: 1px solid #ededed;
94 | display: list-item;
95 | }
96 |
97 | .todo-list todo-item:last-child {
98 | border-bottom: none;
99 | }
100 |
101 | .footer {
102 | color: #777;
103 | padding: 10px 15px;
104 | height: 20px;
105 | text-align: center;
106 | border-top: 1px solid #e6e6e6;
107 | }
108 |
109 | .footer:before {
110 | content: '';
111 | position: absolute;
112 | right: 0;
113 | bottom: 0;
114 | left: 0;
115 | height: 50px;
116 | overflow: hidden;
117 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
118 | 0 8px 0 -3px #f6f6f6,
119 | 0 9px 1px -3px rgba(0, 0, 0, 0.2),
120 | 0 16px 0 -6px #f6f6f6,
121 | 0 17px 2px -6px rgba(0, 0, 0, 0.2);
122 | }
123 |
124 | .todo-count {
125 | float: left;
126 | text-align: left;
127 | }
128 |
129 | .todo-count strong {
130 | font-weight: 300;
131 | }
132 |
133 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/list/list.component.html:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/list/list.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { ActivatedRoute } from '@angular/router';
4 | import { Todo } from '../todo';
5 | import { TodoService } from '../todo.service';
6 |
7 | @Component({
8 | selector: 'todo-list',
9 | templateUrl: './list.component.html',
10 | styleUrls: ['./list.component.css']
11 | })
12 | export class TodoListComponent {
13 | newTodo: Todo = new Todo();
14 | todos: Todo[];
15 | title: string;
16 |
17 | constructor(private todoService: TodoService, private route: ActivatedRoute) {
18 | this.todos = this.route.snapshot.data['todos'];
19 | this.title = this.route.data['title'];
20 | }
21 |
22 | addTodo() {
23 | if (!this.newTodo.title.trim()) {
24 | return;
25 | }
26 | this.todoService.addTodo(this.newTodo);
27 | this.newTodo = new Todo();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/todo.guards.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { CanActivate, CanActivateChild, CanDeactivate, Router,
3 | ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
4 |
5 | import { AuthService } from '../services/auth.service';
6 | import { TodoDetailComponent } from './detail/detail.component';
7 |
8 | @Injectable()
9 | export class MyTodoGuard implements CanActivate, CanActivateChild {
10 |
11 | constructor(private authService: AuthService, private router: Router) {}
12 |
13 | canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
14 | console.log('can activate: ', next.url[0].path);
15 | let requiredRole = next.data['role'];
16 | console.log('Require role: ', requiredRole);
17 | if (!this.authService.isLogdedin()) {
18 | alert('You need to login!');
19 | this.router.navigate(['/home']);
20 | return false;
21 | }
22 | if (requiredRole == null || this.authService.hasRole(requiredRole)) {
23 | return true;
24 | }
25 | return false;
26 | }
27 |
28 | canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
29 | console.log('can activate child: ', childRoute.url[0].path);
30 | return this.canActivate(childRoute, state);
31 | }
32 | }
33 |
34 | @Injectable()
35 | export class CanLeaveTodoDetailGuard implements CanDeactivate {
36 | canDeactivate(component: TodoDetailComponent, route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
37 | return confirm('Confirm?');
38 | }
39 | }
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/todo.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule, ModuleWithProviders } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule } from '@angular/forms';
4 |
5 | import { TodoListComponent } from './list/list.component';
6 | import { TodoDetailComponent } from './detail/detail.component';
7 | import { TodoItemComponent } from './item/item.component';
8 | import { TodoService } from './todo.service';
9 | import { MyTodoResolver } from './todo.resolver';
10 | import { MyTodoGuard, CanLeaveTodoDetailGuard } from './todo.guards';
11 | import { TodoRoutingModule } from './todo.routes';
12 |
13 | @NgModule({
14 | imports: [CommonModule, FormsModule, TodoRoutingModule ],
15 | declarations: [TodoListComponent, TodoDetailComponent, TodoItemComponent],
16 | providers: [TodoService, MyTodoResolver, MyTodoGuard, CanLeaveTodoDetailGuard]
17 | })
18 | export class TodoModule {}
19 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/todo.resolver.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
3 |
4 | import { Observable } from 'rxjs/Observable';
5 |
6 | import { Todo } from './todo';
7 | import { TodoService } from './todo.service';
8 |
9 | @Injectable()
10 | export class MyTodoResolver implements Resolve {
11 |
12 | constructor(private todoService: TodoService) { }
13 |
14 | resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
15 | console.log('Get my todo list.');
16 | return this.todoService.getAllTodos();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/todo.routes.ts:
--------------------------------------------------------------------------------
1 | import { Routes, RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 |
4 | import { TodoListComponent } from './list/list.component';
5 | import { TodoDetailComponent } from './detail/detail.component';
6 |
7 | import { MyTodoGuard, CanLeaveTodoDetailGuard } from './todo.guards';
8 | import { MyTodoResolver } from './todo.resolver';
9 |
10 | const TodoRoutes: Routes = [
11 | {
12 | path: 'list',
13 | component: TodoListComponent,
14 | canActivate: [MyTodoGuard],
15 | resolve: {
16 | todos: MyTodoResolver
17 | },
18 | data: {
19 | role: 'CUSTOMER',
20 | title: '列表'
21 | }
22 | },
23 | {
24 | path: 'detail/:id',
25 | component: TodoDetailComponent,
26 | canActivate: [MyTodoGuard],
27 | canDeactivate: [ CanLeaveTodoDetailGuard ],
28 | data: {
29 | role: 'CUSTOMER',
30 | title: '详情'
31 | }
32 | }
33 | ];
34 |
35 | @NgModule({
36 | imports: [ RouterModule.forChild(TodoRoutes) ],
37 | exports: [ RouterModule ]
38 | })
39 | export class TodoRoutingModule { }
40 |
41 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/todo.service.ts:
--------------------------------------------------------------------------------
1 | import {Injectable} from '@angular/core';
2 | import {Todo} from './todo';
3 |
4 | import { Observable } from 'rxjs/Observable';
5 | import 'rxjs/add/observable/of';
6 | import 'rxjs/add/operator/delay';
7 |
8 | @Injectable()
9 | export class TodoService {
10 |
11 | // 为了生成一个自增的id,保存最后一个生成的id
12 | lastId: number = 0;
13 | todos: Todo[] = []; // 任务列表
14 |
15 | constructor() {
16 | console.log('TodoService created.');
17 | }
18 |
19 | // 添加一个任务
20 | addTodo(todo: Todo): TodoService {
21 | if (!todo.id) {
22 | todo.id = ++this.lastId;
23 | }
24 | this.todos.push(todo);
25 | return this;
26 | }
27 |
28 | // 从任务列表里删除一个任务
29 | deleteTodoById(id: number): TodoService {
30 | this.todos = this.todos.filter(todo => todo.id !== id);
31 | return this;
32 | }
33 |
34 | // 更新一个任务
35 | updateTodoById(id: number, values: Object = {}): Todo {
36 | let todo = this.getTodoById(id);
37 | if (!todo) {
38 | return null;
39 | }
40 | Object.assign(todo, values);
41 | return todo;
42 | }
43 |
44 | getAllTodos(): Observable {
45 | let todo1 = new Todo();
46 | todo1.id = 1;
47 | todo1.title = 'test task 1';
48 | todo1.createdDate = new Date();
49 | todo1.complete = false;
50 | let todo2 = new Todo();
51 | todo2.id = 2;
52 | todo2.title = 'test task 2';
53 | todo2.createdDate = new Date();
54 | todo2.complete = false;
55 |
56 | this.todos = [todo1, todo2];
57 | return Observable.of(this.todos).delay(1000);
58 | }
59 |
60 | getTodoById(id: number): Todo {
61 | return this.todos.filter(todo => todo.id === id).pop();
62 | }
63 |
64 | // 标记一个任务为完成/未完成
65 | toggleTodoComplete(todo: Todo){
66 | let updatedTodo = this.updateTodoById(todo.id, {
67 | complete: !todo.complete
68 | });
69 | return updatedTodo;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/app/todo/todo.ts:
--------------------------------------------------------------------------------
1 | export class Todo {
2 | id: number;
3 | title: string = '';
4 | createdDate: Date = new Date();
5 | complete: boolean = false;
6 |
7 | constructor() { }
8 | }
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mavlarn/angular2-tutorial/6fb614e815700cdd055f0558845852fa7e43b797/angular2-routes-lazy-module-webpack/src/assets/.gitkeep
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // The file contents for the current environment will overwrite these during build.
2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
4 | // The list of which env maps to which file can be found in `angular-cli.json`.
5 |
6 | export const environment = {
7 | production: false
8 | };
9 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mavlarn/angular2-tutorial/6fb614e815700cdd055f0558845852fa7e43b797/angular2-routes-lazy-module-webpack/src/favicon.ico
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Angular2RoutesLazyModule
6 |
7 |
8 |
9 |
10 |
11 |
12 | Loading...
13 |
14 |
15 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/main.ts:
--------------------------------------------------------------------------------
1 | import './polyfills.ts';
2 |
3 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
4 | import { enableProdMode } from '@angular/core';
5 | import { environment } from './environments/environment';
6 | import { AppModule } from './app/';
7 |
8 | if (environment.production) {
9 | enableProdMode();
10 | }
11 |
12 | platformBrowserDynamic().bootstrapModule(AppModule);
13 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | // This file includes polyfills needed by Angular 2 and is loaded before
2 | // the app. You can add your own extra polyfills to this file.
3 | import 'core-js/es6/symbol';
4 | import 'core-js/es6/object';
5 | import 'core-js/es6/function';
6 | import 'core-js/es6/parse-int';
7 | import 'core-js/es6/parse-float';
8 | import 'core-js/es6/number';
9 | import 'core-js/es6/math';
10 | import 'core-js/es6/string';
11 | import 'core-js/es6/date';
12 | import 'core-js/es6/array';
13 | import 'core-js/es6/regexp';
14 | import 'core-js/es6/map';
15 | import 'core-js/es6/set';
16 | import 'core-js/es6/reflect';
17 |
18 | import 'core-js/es7/reflect';
19 | import 'zone.js/dist/zone';
20 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/test.ts:
--------------------------------------------------------------------------------
1 | import './polyfills.ts';
2 |
3 | import 'zone.js/dist/long-stack-trace-zone';
4 | import 'zone.js/dist/proxy.js';
5 | import 'zone.js/dist/sync-test';
6 | import 'zone.js/dist/jasmine-patch';
7 | import 'zone.js/dist/async-test';
8 | import 'zone.js/dist/fake-async-test';
9 | import { getTestBed } from '@angular/core/testing';
10 | import {
11 | BrowserDynamicTestingModule,
12 | platformBrowserDynamicTesting
13 | } from '@angular/platform-browser-dynamic/testing';
14 |
15 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
16 | declare var __karma__: any;
17 | declare var require: any;
18 |
19 | // Prevent Karma from running prematurely.
20 | __karma__.loaded = function () {};
21 |
22 | // First, initialize the Angular testing environment.
23 | getTestBed().initTestEnvironment(
24 | BrowserDynamicTestingModule,
25 | platformBrowserDynamicTesting()
26 | );
27 | // Then we find all the tests.
28 | let context = require.context('./', true, /\.spec\.ts/);
29 | // And load the modules.
30 | context.keys().map(context);
31 | // Finally, start Karma to run the tests.
32 | __karma__.start();
33 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "",
4 | "declaration": false,
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "lib": ["es6", "dom"],
8 | "mapRoot": "./",
9 | "module": "es6",
10 | "moduleResolution": "node",
11 | "outDir": "../dist/out-tsc",
12 | "sourceMap": true,
13 | "target": "es5",
14 | "typeRoots": [
15 | "../node_modules/@types"
16 | ]
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | // Typings reference file, you can add your own global typings here
2 | // https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html
3 |
--------------------------------------------------------------------------------
/angular2-routes-lazy-module-webpack/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "class-name": true,
7 | "comment-format": [
8 | true,
9 | "check-space"
10 | ],
11 | "curly": true,
12 | "eofline": true,
13 | "forin": true,
14 | "indent": [
15 | true,
16 | "spaces"
17 | ],
18 | "label-position": true,
19 | "max-line-length": [
20 | true,
21 | 140
22 | ],
23 | "member-access": false,
24 | "member-ordering": [
25 | true,
26 | "static-before-instance",
27 | "variables-before-functions"
28 | ],
29 | "no-arg": true,
30 | "no-bitwise": true,
31 | "no-console": [
32 | true,
33 | "debug",
34 | "info",
35 | "time",
36 | "timeEnd",
37 | "trace"
38 | ],
39 | "no-construct": true,
40 | "no-debugger": true,
41 | "no-duplicate-variable": true,
42 | "no-empty": false,
43 | "no-eval": true,
44 | "no-inferrable-types": true,
45 | "no-shadowed-variable": true,
46 | "no-string-literal": false,
47 | "no-switch-case-fall-through": true,
48 | "no-trailing-whitespace": true,
49 | "no-unused-expression": true,
50 | "no-use-before-declare": true,
51 | "no-var-keyword": true,
52 | "object-literal-sort-keys": false,
53 | "one-line": [
54 | true,
55 | "check-open-brace",
56 | "check-catch",
57 | "check-else",
58 | "check-whitespace"
59 | ],
60 | "quotemark": [
61 | true,
62 | "single"
63 | ],
64 | "radix": true,
65 | "semicolon": [
66 | "always"
67 | ],
68 | "triple-equals": [
69 | true,
70 | "allow-null-check"
71 | ],
72 | "typedef-whitespace": [
73 | true,
74 | {
75 | "call-signature": "nospace",
76 | "index-signature": "nospace",
77 | "parameter": "nospace",
78 | "property-declaration": "nospace",
79 | "variable-declaration": "nospace"
80 | }
81 | ],
82 | "variable-name": false,
83 | "whitespace": [
84 | true,
85 | "check-branch",
86 | "check-decl",
87 | "check-operator",
88 | "check-separator",
89 | "check-type"
90 | ],
91 |
92 | "directive-selector": [true, "attribute", "app", "camelCase"],
93 | "component-selector": [true, "element", "app", "kebab-case"],
94 | "use-input-property-decorator": true,
95 | "use-output-property-decorator": true,
96 | "use-host-property-decorator": true,
97 | "no-input-rename": true,
98 | "no-output-rename": true,
99 | "use-life-cycle-interface": true,
100 | "use-pipe-transform-interface": true,
101 | "component-class-suffix": true,
102 | "directive-class-suffix": true,
103 | "no-access-missing-member": true,
104 | "templates-use-public": true,
105 | "invoke-injectable": true
106 | }
107 | }
108 |
--------------------------------------------------------------------------------