前回の続きで今回はTodosを作ってみる。Todosはいたるところで書かれているので「Hello World」的には良いかと思う。普通に書き進めるのもどうかなと思うのでAngular1で書いたTodosをAngular2に書き換える感じで記載する。UIとしてはBootstrapを利用しています。
Todos in Angular1
コントローラーとHTMLはだいぶ前に書いたものを利用します。
(component/todo/todo.html)
<h2>Todo</h2> <!-- Todos input --> <form role="form" ng-submit="todo.addTodo()"> <div class="input-group"> <input type="text" ng-model="todo.item" placeholder="What needs to be done?" class="form-control"> <span class="input-group-btn"> <input type="submit" class="btn btn-primary" value="Add" name="add"> </span> </div> </form> <hr> <!-- Todos list --> <div> <p class="input-group" ng-repeat="data in todo.todoList track by $index"> <input type="text" ng-model="data" class="form-control"> <span class="input-group-btn"> <button class="btn btn-danger" ng-click="todo.removeTodo($index)" aria-label="Remove">X</button> </span> </p> </div>
JavaScriptはJohnpapaに従う
(component/todo/todo.js)
(function () { 'use strict'; angular .module('TodoApp.components.todo', []) .controller('TodoController', TodoController); TodoController.$inject = []; var vm; function TodoController() { vm = this; vm.todoList = []; } TodoController.prototype.addTodo = function () { vm.todoList.push(vm.item); vm.item = ''; }; TodoController.prototype.removeTodo = function (index) { vm.todoList.splice(index, 1); }; })();
ルーターやindex.htmlもありますのでgithubを確認してください。
GitHub - albatrosary/Angular1Study at step5: Comprehensive Beginner’s Guide to Angular
Todos in Angular2
Angular1で書いたTodosをAngular2に書き換えます。HTMLは
- todo. を削除
- ng-submit -> (ngSubmit)
- ng-model -> [(ngModel)]
- ng-repeat -> *ngFor
- data in todo.todoList -> #data of todoList
- ng-model -> [value]
- ng-click -> (click)
で変え次のようにした。この変更はなかなか大変そう。
<h2>Todo</h2> <!-- Todos input --> <form role="form" (ngSubmit)="addTodo()"> <div class="input-group"> <input type="text" [(ngModel)]="item" placeholder="What needs to be done?" class="form-control"> <span class="input-group-btn"> <input type="submit" class="btn btn-primary" value="Add" name="add"> </span> </div> </form> <hr> <!-- Todos list --> <div> <p class="input-group" *ngFor="#data of todoList; #idx = index"> <input type="text" [value]="data" class="form-control"> <span class="input-group-btn"> <button class="btn btn-danger" (click)="removeTodo(idx)" aria-label="Remove">X</button> </span> </p> </div>
ngForであるがJavaScriptのfor .. in
とfor ... of
には明確な違いがあります。想像ですが今回in
からof
へ変更したのはfor
文であるというのもありますが、こうした背景もあるのではと勝手に思っています。
var arr = [ 3, 5, 7 ]; arr.foo = "hello"; for (var i in arr) { console.log(i); // "0", "1", "2", "foo" を出力 } for (var i of arr) { console.log(i); // "3", "5", "7" を出力 }
JavaScriptはAngular1のメソッドをそのまま利用した。
(function(app) { var vm; function Todo() { vm = this; this.todoList = []; } Todo.prototype.addTodo = function () { vm.todoList.push(vm.item); vm.item = ''; }; Todo.prototype.removeTodo = function (index) { vm.todoList.splice(index, 1); }; app.TodoComponent = ng.core .Component({ selector: 'app-todo', templateUrl: 'components/todo/todo.html' }) .Class({ constructor: Todo }); })(window.app || (window.app = {}));
ルータ等あるので完全なコードはgithubを見て下さい
最後に
Todosくらいだとプロジェクトコードを書き換えるのとはわけが違いますが、概ねHTMLをAngular1からAngular2へ書き換えるのは大変そう。Angular1のControllerをAngular2のComponentに書き換えるのはJohnpapaのようなスタイルに従っていれば楽そうかな。