SlideShare a Scribd company logo
2014/07/27 @jsCafe21
サーバサイドで動的にhtml生成していたり
jQueryをガッツし使っている
既存プロジェクトにAngularJSを
部分的につっこんでみた
名前:佐藤俊輔
twitter : @ushisantoasobu
所属 : 株式会社ジークレスト
経歴 : 主にフロントエンドエンジニア
担当 : 現在はポケットランド(スマホweb)というアバターサービス
自己紹介
その前の発表がVue.jsで、そこでおそらく
Angularがディスられるので省略
Angularとは
「AngularってSPAつくるためのものでしょ?」
自分の勝手な思い込み
- Rebuild 27
- mozaic.fm #3 (こちらはAngularのみを70分くらい)
「ハイブリッド」もありのようだ
- step1 : データバインディングで効率化
- step2 : 共通モジュールをディレクティブ化
- step3 : 中規模程度の新機能をSPAっぽく
担当プロジェクトでのAngular導入ステップ
- step1 : データバインディングで効率化 ✓
- step2 : 共通モジュールをディレクティブ化 ✓
- step3 : 中規模程度の新機能をSPAっぽく
担当プロジェクトでのAngular導入ステップ
データバインディング
<p>{{message}}</p>
$scope.message = “hoge”;
.html
.js
使っているところ = xhrで表示更新するところ
(初期表示のhtmlについてはJavaのvelocityで生成している)
サーバサイドで動的にhtml生成していたりjQueryをガッツし使っている既存プロジェクトにAngularJSを部分的につっこんでみた @jscafe21
サーバサイドで動的にhtml生成していたりjQueryをガッツし使っている既存プロジェクトにAngularJSを部分的につっこんでみた @jscafe21
- ゲームのポイントやランキング
- アイテム所持数
- 報酬アイテム
などなど...結構ある
- 同じデータを表示する箇所が複数あっても安心
- データのオブジェクトさえつっこめばいいので楽
(もうjQueryではやりたくない)
特にいいと思ったところ
同じデータを複数のDOMで表示することが多々ある
<div class=”point_total”>×{{targetRewardPoint}}</div>
...
<div class=”point_total”>×{{targetRewardPoint}}</div>
...
<div class=”result_point_total”>×{{targetRewardPoint}}</div>
.html
<div class=”point_total”>×{{targetRewardPoint}}</div>
...
<div class=”point_total”>×{{targetRewardPoint}}</div>
...
<div class=”result_point_total”>×{{targetRewardPoint}}</div>
$scope.targetRewardPoint = data.point;
.html
.js
もちろんこれだけでOK
{
" "bannerDataList":null,
" "boxLevelBonusAchieveLevel":1,
" "boxLevelBonusList":[],
" "completeFlg":false,
" "completePoint":0,
" "countRewardDataList":null,
" "currentPoint":327,
" "currentRank":27910,
" "deliveryCount":0,
" "deliveryCountRewardDataList":null,
" "orderPoint":0,
" "pointRewardDataList":[
" " {
" " " "categoryName":"アクセサリ/手系",
" " " "count":1,
" " " "dataItemFlg":false,
" " " "imageUrl":"shop/clothes/acceh/acceh_10824494_shop.png",
" " " "itemId":10824494,
" " " "itemName":"ふしぎな実",
" " " "itemRare":0,
" " " "rewardPoint":300
" " }
" ],
" "restRewardCount":55,
" "resultCd":0,
" "token":null
}
あるAPIでこのようなjsonが返ってくるとする
{
" "bannerDataList":null,
" "boxLevelBonusAchieveLevel":1,
" "boxLevelBonusList":[],
" "completeFlg":false,
" "completePoint":0,
" "countRewardDataList":null,
" "currentPoint":327,
" "currentRank":27910,
" "deliveryCount":0,
" "deliveryCountRewardDataList":null,
" "orderPoint":0,
" "pointRewardDataList":[
" " {
" " " "categoryName":"アクセサリ/手系",
" " " "count":1,
" " " "dataItemFlg":false,
" " " "imageUrl":"shop/clothes/acceh/acceh_10824494_shop.png",
" " " "itemId":10824494,
" " " "itemName":"ふしぎな実",
" " " "itemRare":0,
" " " "rewardPoint":300
" " }
" ],
" "restRewardCount":55,
" "resultCd":0,
" "token":null
}
枠部分(報酬アイテム情報)を表示したい
<div>
" <div>
" <img src="http://img.atgames.jp/sp/update/2014/04/icon_point.png">
" " <span id=”reward_span_reward_point”></span>達成
" </div>
" <div><img id=”reward_img_reward_url”></div>
" <div id=”reward_div_reward_itemname”></div>
" <div id=”reward_div_reward_itemcount”></div>
</div>
var reward = data.pointRewardData[0];
jQuery(“#reward_span_reward_point”).html(reward.rewardPoint);
jQuery(“#reward_img_reward_url”).attr('src', reward.imageUrl);
jQuery(“#reward_div_reward_itemname”).html(“<em>” + reward.categoryName +
“</em><br>” + reward.itemName);
jQuery(“#reward_div_reward_itemcount”).html(“×” + reward.count);
.html
.js
これまで自分がjQueryで書いてた方法(もっとキレイに書ける?汗)
AngularJSで書いた方法。ロジック側の記述が楽
<div>
" <div>
" " <img src="http://img.atgames.jp/sp/update/2014/04/icon_point.png">
" " <span>{{pointRewardData.rewardPoint}}</span>達成
" </div>
" <div><img src="http://img.atgames.jp/{{pointRewardData.imageUrl}}"></div>
" <div><em>{{pointRewardData.categoryName}}</em><br>{{pointRewardData.itemName}}</div>
" <div ng-show="pointRewardData.count > 1">×{{pointRewardData.count}}</div>
</div>
$scope.pointRewardDataList = pointRewardDataList;
.html
.js
負の遺産もつくってしまった、、、恥ずかしいけど書く
サーバサイドで動的にhtml生成していたりjQueryをガッツし使っている既存プロジェクトにAngularJSを部分的につっこんでみた @jscafe21
ページ表示時に
サーバサイドで動的に値を埋め込んでいる、
でもその後xhrでも値を更新したい、
といった箇所
<!-- 初期表示にvelocityで値を埋め込みたい -->
<p>$!{rank}</p>
<!-- でもangularでも書きたい(どんどん更新していくので) -->
<p>{{rank}}</p>
.html
.js
$scope.rank = 0;
どうする?
<p>{{rank}}</p>
 
 
<script>
var setupAngular = function(){
" var _scope = angular.element(ngCtrl).scope();
" _scope.$apply(function(){
" " _scope.rank = $!{rank};
" });
};
</script>
.html
.js
$scope.rank = 0;
 
angular.element(document).ready(function() {
" if(setupAngular && typeof setupAngular === "function"){
" " setupAngular(); //本体htmlのグローバルメソッドにアクセス
" }
});
html側のスクリプトにvelocityで吐き出される値を書き出して、、、
みたいなことをやってる。しかも不要にグローバル変数をつくってしまってる
- 簡単にいえば「カスタムタグ」or「カスタム属性」
ディレクティブ
サーバサイドで動的にhtml生成していたりjQueryをガッツし使っている既存プロジェクトにAngularJSを部分的につっこんでみた @jscafe21
サーバサイドで動的にhtml生成していたりjQueryをガッツし使っている既存プロジェクトにAngularJSを部分的につっこんでみた @jscafe21
サービス内の複数のページで共通で使用している機能
をディレクティブ化する
ディレクティブ化する前
イベント毎にソースをコピペして、値の一部を変えることで対応していた(惰性)
<canvas id=” canvas_100522”></canvas>
<script>
(function(){
" var self = {}, canvas, stage, exportRoot,
" POS_X = 0, POS_Y = 0, SCALE = 0.55; //※ここ調整する
"
" self.init = function() {
" " canvas = document.getElementById("canvas_100522");
" " df100522_images = df100522_images||{};
 
" " var len = df100522.properties.manifest.length;
" " for(var i = 0; i < len; i++){
" " " var url = df100522.properties.manifest[i].src;
" " " url = window.IMAGE_DOMAIN + "/high/roomfurniture/deco/" + url;
" " " df100522.properties.manifest[i].src = url;
" " }
 
" " var loader = new createjs.LoadQueue(false);
" " loader.addEventListener("fileload", self.handleFileLoad);
" " loader.addEventListener("complete", self.handleComplete);
" " loader.loadManifest(df100522.properties.manifest);
" }
 
" self.handleFileLoad = function(evt) {
"" if (evt.item.type == "image") { df100522_images[evt.item.id] = evt.result; }
" }
 
" self.handleComplete = function() {
"" //ここは省略
" }
 
" window.selfytown.df100522_shop = self;
}());
</script>
.html
ディレクティブ化する
.directive('df', function() {
" return {
" " restrict: 'E',
" " transclude: true,
" " scope: {
" " " furnitureid: '@',
" " " category: '@',
" " " posx: '@',
" " " posy: '@',
" " " scale: '@'
" " },
" " template:
" " " '<canvas id="js_canvas_dynamic_furniture_{{furnitureid}}"></canvas>',
" " link:function($scope, $element){
 
" " " var canvas,
" " " " len,
" " " " url,
" " " " loader,
" " " " exportRoot,
" " " " stage;
" " "
" " " canvas = $element[0];
 
" " " len = window["df" + $scope.furnitureid].properties.manifest.length;
" " " for(i = 0; i < len; i++){
" " " " url = window["df" + $scope.furnitureid].properties.manifest[i].src;
" " " " url = window.IMAGE_DOMAIN + "/high/roomfurniture/" + $scope.category + "/" + url;
" " " " window["df" + $scope.furnitureid].properties.manifest[i].src = url;
" " " }
 
" " " //CreateJSまわりの処理は省略
" " },
" " replace: true
" };
});
.js
ディレクティブ化した後
<df furnitureid=”100522” category=”deco” posX=”0” posY=”0” scale=”0.55”></df>
.html
以後これだけでOK(でもやっぱ黒魔術的な匂いがする)
- ディレクティブの使いどころについては
@konpyuさんのスライドがわかりやすかった
http://www.slideshare.net/KonYuichi/0601-angular-note
- mozaic.fm #3 でもゲストでお話されています!
- 中規模程度の機能をSPAっぽくつくりたい
SPAっぽくつくりたい
サーバサイドで動的にhtml生成していたりjQueryをガッツし使っている既存プロジェクトにAngularJSを部分的につっこんでみた @jscafe21
イベントページのタブボタン押下時の画面の切り替えを
今はページ読み込みになっているけど
APIだけ返してもらっての表示の切り替えにしたい
- アプリっぽい挙動にしたい = サクサク感
やりたいこと
- フロントまわりでの処理が多くなるので
機種やOSによっては逆に描画が遅くなるかも?
- htmlをキャッシュさせることでSPAを実現するけど
htmlの更新の仕組みをうまくつくらないと
- 既存のワークフロー(webコーダー、サーバサイド)
から見直さないといけない
懸念事項
- jQueryも使える(angular.element)
- 動的に表示を更新してく箇所がたくさんあるときは
jQueryではもう書けない、
でも必ずしもAngularでなくてもよい?
まとめや補足
- 改めて振り返ると、、初期学習コストは高いかも
- html自体がテンプレートになっているので
webコーダーもみやすい
- でも急に見知らぬカスタムタグつくるとビックリ
されて迷惑がられる
まとめや補足
- Angularっぽくないこのスライドの色合いは、
当初はW杯直前に発表する予定だったため
ブラジルカラーっぽくしてるだけ
まとめや補足
ご清聴ありがとうございます!

More Related Content

PDF
JavaScriptでいいじゃなイカ
PDF
Start React with Browserify
PDF
jQuery Mobile 概要
PDF
ソーシャルアプリ勉強会(第一回資料)配布用
PDF
One night Vue.js
PDF
Progressive Framework Vue.js 2.0
PDF
はじめよう Backbone.js
PDF
Creators'night#13 tech#2今井
JavaScriptでいいじゃなイカ
Start React with Browserify
jQuery Mobile 概要
ソーシャルアプリ勉強会(第一回資料)配布用
One night Vue.js
Progressive Framework Vue.js 2.0
はじめよう Backbone.js
Creators'night#13 tech#2今井

What's hot (20)

PDF
SVG MANIAX Ver.2 - Mars vanilla
PDF
Web socketドロンくん その後-
PDF
The master plan of scaling a web application
PDF
Backbonejs @BuildInsiderOffline #1
PDF
Velocity.js is next generation animation engine.
KEY
Kawaz的jQuery入門
PDF
HTML5 と SVG で考える、これからの画像アクセシビリティ
PDF
Canvas勉強会
PDF
Angular js or_backbonejs
PPTX
忙しい人のためのBackbone.jsとAngular.js入門
PPTX
React を導入した フロントエンド開発
PPTX
Vue.js 2.0を試してみた
PDF
backbone.jsの使用例 その1
PDF
iOS の通信における認証の種類とその取り扱い
PDF
Scc2014 :jQueryの仕組みを完璧に理解する
PDF
Backbone.js入門
PDF
はじめてのVue.js
PDF
初めてのvue.js(2.x系)
PDF
iOS WebView App
PDF
HTML5のCanvas入門 - Img画像を編集してみよう -
SVG MANIAX Ver.2 - Mars vanilla
Web socketドロンくん その後-
The master plan of scaling a web application
Backbonejs @BuildInsiderOffline #1
Velocity.js is next generation animation engine.
Kawaz的jQuery入門
HTML5 と SVG で考える、これからの画像アクセシビリティ
Canvas勉強会
Angular js or_backbonejs
忙しい人のためのBackbone.jsとAngular.js入門
React を導入した フロントエンド開発
Vue.js 2.0を試してみた
backbone.jsの使用例 その1
iOS の通信における認証の種類とその取り扱い
Scc2014 :jQueryの仕組みを完璧に理解する
Backbone.js入門
はじめてのVue.js
初めてのvue.js(2.x系)
iOS WebView App
HTML5のCanvas入門 - Img画像を編集してみよう -
Ad

Viewers also liked (8)

PDF
小さな会社(チーム)で クールなアプリをつくる方法 Gunosy UI Design Study #1
PPTX
アジャイルとクラウドの『危険なカンケイ』
PDF
はじめてのアジャイル - Agile in a nutshell
PDF
Prott Story ( Prottができるまで )
PDF
インフラエンジニアのためのRancherを使ったDocker運用入門
PPT
Ameba流 scrumを浸透させていく方法
PDF
5分で分かるアジャイルムーブメントの歴史 拡大版
PDF
株式会社Gunosy fix
小さな会社(チーム)で クールなアプリをつくる方法 Gunosy UI Design Study #1
アジャイルとクラウドの『危険なカンケイ』
はじめてのアジャイル - Agile in a nutshell
Prott Story ( Prottができるまで )
インフラエンジニアのためのRancherを使ったDocker運用入門
Ameba流 scrumを浸透させていく方法
5分で分かるアジャイルムーブメントの歴史 拡大版
株式会社Gunosy fix
Ad

Similar to サーバサイドで動的にhtml生成していたりjQueryをガッツし使っている既存プロジェクトにAngularJSを部分的につっこんでみた @jscafe21 (19)

PPTX
エンタープライズ分野での実践AngularJS
PDF
AngularJSで業務システムUI部品化
PPTX
JavaScriptテンプレートエンジンで活かすData API
PDF
Objective Front-End JavaScript
PDF
AngularJS 概説
PDF
AngularJSとD3.jsによるインタラクティブデータビジュアライゼーション
PDF
IgGrid 入門編
PDF
HTML5 ビギナーのための AngularJS
KEY
はじめてのCouch db
PPTX
JavaScriptテンプレートエンジンで活かすData API
PDF
Ext.direct
PPT
20130924 Picomon CRH勉強会
PDF
Featuring Project Silk & Liike: 楽しい "モダン" Web 開発のちょっとディープなお話
PDF
Backbone.js
PDF
多分モダンなWebアプリ開発
PDF
エンジニア勉強会_DECIDE
PDF
㉗HTML5+jQueryでお絵かき
PDF
IgChart 入門編
PPTX
HTML5&API総まくり
エンタープライズ分野での実践AngularJS
AngularJSで業務システムUI部品化
JavaScriptテンプレートエンジンで活かすData API
Objective Front-End JavaScript
AngularJS 概説
AngularJSとD3.jsによるインタラクティブデータビジュアライゼーション
IgGrid 入門編
HTML5 ビギナーのための AngularJS
はじめてのCouch db
JavaScriptテンプレートエンジンで活かすData API
Ext.direct
20130924 Picomon CRH勉強会
Featuring Project Silk & Liike: 楽しい "モダン" Web 開発のちょっとディープなお話
Backbone.js
多分モダンなWebアプリ開発
エンジニア勉強会_DECIDE
㉗HTML5+jQueryでお絵かき
IgChart 入門編
HTML5&API総まくり

More from 佐藤 俊太郎 (8)

PDF
iOSオジサンは JSオジサンを これからも覗きにくる
PDF
Source kittenについて
PDF
Bond の v4 について
PDF
`redux`と`flux`を比べてみたときの個人的な感想
PDF
yidev 第18回勉強会 「業務でSwiftで3ヶ月開発してきたので一旦振り返り」
PDF
Createjsについて@jsCafe20
PDF
flasherがはじめてiOS開発をしてみて
KEY
Introduction for cocos2d
iOSオジサンは JSオジサンを これからも覗きにくる
Source kittenについて
Bond の v4 について
`redux`と`flux`を比べてみたときの個人的な感想
yidev 第18回勉強会 「業務でSwiftで3ヶ月開発してきたので一旦振り返り」
Createjsについて@jsCafe20
flasherがはじめてiOS開発をしてみて
Introduction for cocos2d

サーバサイドで動的にhtml生成していたりjQueryをガッツし使っている既存プロジェクトにAngularJSを部分的につっこんでみた @jscafe21