AngularJSのTutorialのstep-10を遂行したレポートになります。
step-10
このstepでは、clickイベント時の処理を実装したデモを通して、課題を遂行します。
clickイベントで、スマホのメイン写真を選択してクリックしたサムネイル写真に切り替えるevent handlerを作成したControllerの抜粋が下記です。
Controller
phonecatControllers.controller('PhoneDetailCtrl', ['$scope', '$routeParams', '$http',
function($scope, $routeParams, $http) {
.... 省略 ...
$scope.setImage = function(imageUrl) {
$scope.mainImageUrl = imageUrl;
}
}]);
この実装を見た時に、あまりにも理にかなっていて逆に違和感を覚えました。
メイン画像設定event handler functionは、スマホ詳細画面のevent handlerでありその他では利用されないものである。
Controllerとevent handler functionの違いメモ
ここで初めて、Controllerで定義するfunctionとevent handler functionの違いをはっきり理解できていなかったことに気づいていた。
Controllerの説明の振り返りになるが、Controllerは、ngControllerディレクティブを持つBlockタグに囲まれた領域内の$scope変数のData Binding が有効になる。または、ngViewで囲まれた領域内でData Bindingが有効になる。
event handler functionは、ngControllerディレクティブもしくはngViewで囲まれた領域内でevent handlerを設置でき、またControllerと同じく$scopeの変更結果は、ngControllerディレクティブもしくはngViewで囲まれた領域内に適用される。
内部的な処理結果の反映は同じである。違いは、
- Controllerは、ページ内にngControllerで指定されているかRoutingで定義したURLにアクセスされたときに詳細が分かる
- event handler functionは、ユーザの操作が操作したときに初めて実行されることになる(event handlerなのだから当然か)。
テスト
...
describe('Phone detail view', function() {
...
it('should display the first phone image as the main phone image', function() {
expect(element('img.phone').attr('src')).toBe('img/phones/nexus-s.0.jpg');
});
it('should swap main image if a thumbnail image is clicked on', function() {
element('.phone-thumbs li:nth-child(3) img').click();
expect(element('img.phone').attr('src')).toBe('img/phones/nexus-s.2.jpg');
element('.phone-thumbs li:nth-child(1) img').click();
expect(element('img.phone').attr('src')).toBe('img/phones/nexus-s.0.jpg');
});
});
});
- デフォルトのメイン画像URLをチェックして
- 3番目のサムネイル画像をクリックして、メイン画像URLが期待する画像になっているかを確認
- 元のメイン画像に戻す
という上記の結果を、e2eテストという形で実装されている。
ここでのデモスクリプトにおけるevent handler function実装の何が嬉しいか?
jQueryでは、各種event handler functionを定義する場合、$(function(){});という無名関数を使う。そして、この時、無名関数に実装された処理について知る方法として、ソースコードを読む以外に、ファイル名もしくはコメントで知ることになる。
大概の場合、特に管理されていない事が多く、一つの無名関数に無数の処理が羅列される。AngularのようにController内に書くルールにすれば、Controller名がパッケージ的な役割で内部実装の明確な目的を与えてくれる。
一つの画面に数々の処理が実装されるような複雑な場合、フィーチャをグルーピングしてControllerを作成することになるのか。