
ã¯ããã«
ã¿ãªããããã«ã¡ã¯ïŒ å°ãåãŸã§ã ãPhalcon + AngularJS + Zurb Foundationã«ãã¹ã±ããã®ãã1ããŒãžã·ã§ããããšããåºçç©ãæžããŸããããæ§ããã«èšã£ãŠããããŸããªå¹æããããŸããã ããããç§ã¯å€ãã®åŠå®çãªã³ã¡ã³ããåãåããŸãããäžéšã¯å®¢èŠ³çã§å»ºèšçã§ãäžéšã¯ããã§ã¯ãããŸããã§ããããããŠãç§ãšä»ã®äººãAnââgularJSã§æžãå§ããã®ã«åœ¹ç«ã€äŸ¿å©ãªããã¥ã¢ã«ãäœãããã£ãã®ã§ããªããããèµ·ãã£ãã®ããšæããŸãã
åçœ
ã¯ããããã¥ã¢ã«ã¯ç§ã«ãšã£ãŠæçšã§ãããç§ã«ãšã£ãŠã¯ã2009幎ã«å°å ã®ãŠã§ãã¹ã¿ãžãªã§ã®ä»äºãæåŠãããå€ããã®ã§ãä»æ¥ãŸã§åœŒã¯ããŒã ã§åããããšã¯ãªããéãããä»äºã§åããããšã¯ãããŸãããããããžã§ã¯ãã®å®è£ ã®æå¹æ§ã®äž»ãªåºæºã¯1ã€ã§ããããããæå¹ãªäž»ãªãã®ã§ãã ããããããã¯ç§ã§ããå€ãèšäºã§ããã®èšäºãæžããåŸãããããã®ã³ã¡ã³ããæžããåŸããŸãã¯è¶£å³ã®ããã ãã«ã趣å³ã®ã«ãŒã«ã«åŸã£ãŠãã¹ãŠãããããšæ±ºããŸããã
åç §è³æ
éåžžãåç §ã®ãªã¹ãã¯æåŸã«ãããŸãããäžæ¹ã§ãèšäºãæžãããŠããããã«ããªããã®ãããªå®è£ ãéžã°ããã®ãçåãçããŸãã ãããŠãããªãã®è³ªåãžã®çããªãã§ããªããå»ããªãããã«ãç§ã¯æ¬åŒ§ã§ç€ºãããŸã[ïŒ]ãããåããããœãŒã¹ã ã ãããããã«ç§ãé Œã£ãæç®ããããç§ã®ééããä¿®æ£ããŠããŸãã
- Phalcon + AngularJS + Zurb Foundationã®ãã¹ã±ããä»ã1ããŒãžã·ã§ããã«é¢ããã³ã¡ã³ã
- ããŒã éçºã®ããã®å€ªåã®AngularJSã¹ã¿ã€ã«ã¬ã€ã[1/2]
- ããŒã éçºã®ããã®å€§èãªAngularJSã¹ã¿ã€ã«ã¬ã€ã[2/2]
- è§åºŠjsïŒng-repeatã¯éè€ãèš±å¯ããªããªããŸãã
- ããŒã«ã«ã¹ãã¬ãŒãžã䜿çšãã
- AngularJS $ httpã¯X-Requested-WithããããŒãéä¿¡ããŸãã
- ngRouteããªããŒããŒã®äŸ
ãšã©ãŒåŠç
1ããŒãžã®é£æååºã®ãããžã§ã¯ãã®å®æœäžã«ã次ã®æ¬ ç¹ãæå³ããã«è¡ãããŸããã
- phpã䜿çšããŠããã¹ãŠã®è£œåãäžåºŠã«1ããŒãžã«ã¢ããããŒãããŸã
- çµ±äžãããã³ãŒãã£ã³ã°ã¹ã¿ã€ã«ã®æ¬ åŠ
- EugeneOZã«ããAngularJSã³ã³ãããŒã©ãŒã§ã®ããžãã¯ã®äœ¿çš[1]
- ãã¿ç®±ãjsãªããžã§ã¯ãã«ä¿åããŸããããã¯ã hVosttã«ãã£ãŠããŒãžã®ãªããŒã[1]åŸã«ãªã»ãããããŸãã
- steppefoxããã€ã³ã©ã€ã³PHPã¹ã¯ãªãã[1]ãæ¿å ¥ããŠãã¹ã±ããã«è¿œå ãã
- æ°ããã«ããŽãªãããŒãããéã®ã€ã³ã¿ãŒãã§ãŒã¹ã®å¿çæ§
ãã®èšäºã§ã¯ãç§ã解決çãæ¢ããæ¹æ³ãšããã®çµæãå ±æããããšæããŸãã ããã§ã¯ãåé ç®ãèŠãŠãããŸãããã
phpã䜿çšããŠããã¹ãŠã®è£œåãäžåºŠã«1ããŒãžã«ã¢ããããŒãããŸã
èšç®ããããããå°ãå€ãã®ååãåºã«ãããç§ãã¡ã®ã«ã ãã£ãã«ã€ã³ã¿ãŒããããèãããšãæã ã¯èšç®ããŸãã
100åã®è£œåïŒç»åïŒãåç»åã¯100ã300 kbãæçµçã«ã¯ãååã ãã10 mbã®éã®é¡§å®¢ã®è²Žéãªãã©ãã£ãã¯ãæ¶è²»ããããã«ãµã€ãèªäœã®ééã¯çŽ10 mbïŒç»åãã¹ã¿ã€ã«ãã¹ã¯ãªããïŒã§ããã ä»ã§ã¯ãã¹ãŠãæé©åããããšãã§ããŸããããã©ãŠã¶ãŒã¯å¿ èŠãªãã®ããã¹ãŠãã£ãã·ã¥ããããããµã€ãã®ééã¯æåã®ããŠã³ããŒãæã«3.9 mbãåŸç¶ã®ããŠã³ããŒãã§ã¯1 mb以äžã§ãã
ãã®ãããªæé©åã¯ãå質ãæãªãããšãªã倧ããªèæ¯ç»åãå§çž®ããããšã§éæãããã¢ã€ã³ã³ãå°ããªã°ã©ãã£ãã¯ã¹ã®ã¹ãã©ã€ããããŒãžã§éèŠãªåœ¹å²ãæãããªãã£ããããã¯ãåé€ãããŸããïŒã¬ãã¥ãŒãããŒãããŒã蚌ææžããªãç§ãã¡ããªãŒãã³ãã£ãŒãããã¯ãã©ãŒã jivositeã«çœ®ãæããããéä¿¡ïŒã ããã§ããé£ã¹ç©ã®ãããµã€ãã®ããŠã³ããŒãé床ã¯ã誰ãå¿ èŠãšããªãæ å ãè³ãããã¯ããã«éèŠã§ãã
ãããŠãã¡ãããæé©åã¯phpã䜿çšããŠãã¹ãŠã®è£œåãäžåºŠã«ããŒãžã«ã¬ã³ããªã³ã°ããããšãæåŠããããã§ããã/ïŒïŒ/ Menu / 7ã®ãããªãªã³ã¯ãã¯ãªãã¯ããŠjsonããŒã¿ãèªã¿èŸŒãajaxã«çœ®ãæããããŸããããangularjsã§ã«ãŒãã£ã³ã°ãã©ã®ããã«æ©èœããããåŠã¶æ©äŒããããŸããæ®å¿µãªããšã«ããã以åã¯jsã«ãŒãã£ã³ã°ã§äœæ¥ããããšããããŸããã§ããã
ãããŠãæã£ãã»ã©é£ãããªãããšãå€æããŸãããå®éãã«ãŒãã¯1ã€ãããããŸããã§ããã
function config($routeProvider, $locationProvider) { $routeProvider .when('/menu/:id', {templateUrl: '/app/views/products.html', controller: ProductsController}); $locationProvider.hashPrefix('!'); $locationProvider.html5Mode(true); } angular.module('rollShop').config(config);
次ã«ããµãŒããŒããjsonããŒã¿ãããŒããããã³ãã¬ãŒãã«ã¬ã³ããªã³ã°ããŸããã
<div class="large-12 columns" ng-view></div>
äžè¬ã«ããã®ã¢ãããŒãã®ã€ã³ããã¯ã¹äœæã®ããã«ããµãŒããŒã¯jsonã§ã¯ãªãhtmlãè¿ãå¿ èŠããããšèããŸããããPHPã¹ã¯ãªããã®ã€ã³ã©ã€ã³æ¿å ¥ãåé¿ããæ¹æ³ã¯æ確ã§ã¯ãããŸãããïŒ ãã®è³ªåã¯ç§ã«ãšã£ãŠè¬ã®ãŸãŸã§ãã ãããŠããã®ã¢ãããŒãã¯å¥ã®åé¡ãåŒãèµ·ãããŸããããŠãŒã¶ãŒãïŒïŒ/ menu / 7ãªã³ã¯ãã¯ãªãã¯ãããšãããŒãžã®æŽæ°ãã¿ã³ãã¯ãªãã¯ãããšã
public function menuAction($id) { if($id != 'undefined') { if ($this->request->isAjax() == true) { // $category = Category::findFirst($id); // $sub_category = Category::find("pid = '" . $id . "'"); if (count($sub_category) > 0) { $products['category'] = $category->name; foreach ($sub_category as $key => $val) { $products['subcategory'][$key] = array( 'name' => $val->name, 'products' => Products::find("category = '" . $val->id . "'")->toArray() ); } } else { $products = array( 'category' => $category->name, 'products' => Products::find("category = '" . $category->id . "'")->toArray() ); } $this->response->setContent(json_encode($products)); return $this->response->send(); } else { $this->response->redirect('/#!/menu/' . $id); return false; } } else { return false; } }
Phalconã§ã®AJAXãªã¯ãšã¹ãã®ãã§ãã¯ã¯ã次ã®æ¡ä»¶ã䜿çšããŠè¡ãããŸãã
if ($this->request->isAjax() == true) { //This is Ajax }
ããããåé¡ããããŸããAngularJSã¯ããã©ã«ãã§ç¹å¥ãªX-Requested-WithããããŒããµãŒããŒã«éä¿¡ããŸãã[6]ãã€ãŸããAngularJSã®å©ãããªããã°ãã®é¢æ°ã¯æ©èœããªããããangular configã«1è¡è¿œå ããå¿ èŠããããŸããã
var app = angular.module('rollShop', ['ngRoute', 'mm.foundation'], function ($httpProvider) { $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest'; }
ããã§ãã¹ãŠãæ©èœãããŠãŒã¶ãŒã«ã¯è£žã®JSONã衚瀺ãããªããªããŸãã
ãšããã§ãã€ã³ããã¯ã¹äœæã®ããã«ããããããã§ãã¯ãããããã«ããããªhtmlããjsã³ãŒããªãã§ããã¿ã³ãªãã§ã補åã ãã§æäŸã§ãããšæããŸããã çå®ã¯ããããããŸãããã®ãããããšãæ£ããã®ãããããªããšããããšã§ãã誰ããã³ã¡ã³ãã§æããŠãããŸããã
ã€ã³ã©ã€ã³PHPã¹ã¯ãªãããæ¿å ¥ããŠãã¹ã±ããã«è¿œå ãã
åã®ãã°ã®ä¿®æ£ã®ãããã§ããã°ã¯jsé¢æ°ã«ã€ã³ã©ã€ã³PHPã¹ã¯ãªãããæ¿å ¥ããããšã§èªåçã«ä¿®æ£ãããŸããã 補åã以åã«ãã¹ã±ããã«è¿œå ãããæ¹æ³ãšãçŸåšã®ç¶æ ãæ¯èŒããŠã¿ãŸãããã
ïŒfuïŒãžïŒ
<div class="add-cart"> <input type="number" ng-model="num<?=$p['id']?> value="1" min="1" max="50"> <button type="button" ng-click="addCart(<?=$p['id']?>, num<?=$p['id']?>, '<?=$p['title']?>', <?=$p['price']?>)"></button> </div>
$scope.addCart = function(id, num, title, price) { var nums = num || 1; $scope.carts.push({ id : id, num : nums, title : title, price : price }); };
åŸïŒ
<div class="add-cart"> <input type="number" ng-model="item.quality" min="1" max="50" placeholder="1"> <button type="button" ng-click="addCart(item)"></button> </div>
$scope.addCart = function (item) { CartsService.addCart(item); };
æ£çŽãªãšããããã®ã¢ãããŒãã¯é¡§å®¢ãé«ãè©äŸ¡ããããã以äžæ¯æãããšããããŸãããããã®ã¢ãããŒããããæ°ã«å ¥ã£ãŠããŸããããããã©ããããããç§ã¯èªåèªèº«ãèªãã«æããå¿ããåãã§ããŸãã
çµ±äžãããã³ãŒãã£ã³ã°ã¹ã¿ã€ã«ã®æ¬ åŠ
åã®2ã€ã®æ¬ ç¹ãä¿®æ£ããªãããããã«2ã€ãä¿®æ£ããå¿ èŠããããŸããããã³ã³ãããŒã©ãŒã§ããžãã¯ã䜿çšãããããšã§ããµãŒãã¹ããã¹ãŠãå®è¡ã§ããããšãšããåäžã¹ã¿ã€ã«ã®ã³ãŒãäœæã®æ¬ åŠãã確èªã§ããŸãã
ããã¯ç§ã®æ°žé ã®åé¡ã§ãããç¹°ãè¿ããŸãããçµæžåŠãšãäž»ãªãã®ãæ©èœããŠãããã¢ãããŒãã®èŠ³ç¹ããèŠããšãã¹ã¿ã€ã«ã¬ã€ãã«ç ©ããããããšãªãããã¹ãŠãããã§éåžžã«å¹æçã§ããç§ã¯å€ãã®æéãšãéãç¯çŽããŸããã ã¡ãªã¿ã«ãç§ã®ã¯ã©ã€ã¢ã³ãã®äºç®ã¯5äžãã10äžã«ãŒãã«ã§ãããã³ãŒãã®èšè¿°æ¹æ³ã¯æ°ã«ããŸããã ããããããã¯ãã¹ãŠæ£åœåã§ããç¶æ³ãä¿®æ£ããã³ãŒããçŸãããèªã¿ããããè«ççã«ãããã®ã§ããããã¯ãHabré[2]ãš[3]ã«é¢ãã2ã€ã®èšäºã«ãã£ãŠå©ããããŸããã
ãã®çµæã2ã€ã®ã³ã³ãããŒã©ãŒã3ã€ã®å·¥å Žã1ã€ã®ãã¥ãŒã1ã€ã®äžè¬çãªapp.jsãååŸããŸããã ããã¯æ¬¡ã®ããã«ãªããŸãã

å®éããããã®ã¹ã¿ã€ã«ã¬ã€ãã§æšå¥šãããŠãããšããã§ãã ããã§ã¯ãã³ã³ãããŒã©ãŒãèŠãŠã¿ãŸãããã以åã®èšäºãšæ¯èŒã§ããŸãã
ProductsController.js
function ProductsController($scope, $routeParams, ProductsService, CartsService) { $scope.items = ''; ProductsService.getData($routeParams.id).success(function(data){ $scope.items = data; }); $scope.addCart = function (item) { CartsService.addCart(item); }; } angular.module('rollShop').controller('ProductsController', ProductsController);
CartsController.js
function CartController($scope, CartsService) { $scope.carts = CartsService.getItemsCart(); $scope.total = function(){ return CartsService.summary($scope.delivery) }; $scope.removeItem = function (carts, item) { CartsService.removeItem(carts, item); }; } angular.module('rollShop').controller('CartController', CartController);
ç§ã«ãšã£ãŠã¯ããã¹ãŠãã¯ãŒã«ãªããã§ããç§èªèº«ãã以åãããããããã³ã³ãããŒã©ãŒã§ä»¥åã«èµ·ãã£ãããšãããæ°ã«å ¥ã£ãŠããŸãã
ããŒãžã®ãªããŒãåŸã«ãªã»ãããããjsãªããžã§ã¯ãã«ãã¿ç®±ãä¿åãã
èªè ããŸãæ°ã¥ãã次ã®æ¬ ç¹ã¯ãjsãªããžã§ã¯ãã«ãã¹ã±ããååãä¿ç®¡ããããšã§ãã ãã®ã¢ãããŒããéžãã çç±ã¯ãã¹ãã¢ãåäžããŒãžã§ãããããåã®èšäºã§èª¬æããŸããã ãããã«ãããlocalStorageã«ã¹ãã¬ãŒãžãå®è£ ããããšã¯é£ãããªããå°æ¥çã«ã¯åœ¹ã«ç«ã€ãšæããŸãã
localStorageã§åäœããAngularJSã®äŸ¿å©ãªã¢ãžã¥ãŒã«ãæ¢ãå§ããŸããããåæã«ã·ã³ãã«ã§ç°¡åãªã¯ãã§ãã ããã€ãã®å®è£ ãªãã·ã§ã³ãèŠã€ããŸããããç§ã®æèŠã§ã¯è€éã§å€§ããªãã®ã§ãããæ®å¿µãªããšã«ä»ã¯ãªã³ã¯ãèŠããŠããŸããããããŠãç§ã ãã®ãªãã·ã§ã³ã«åºäŒããŸãã[5]ã
angular.module('ionic.utils', []) .factory('$localstorage', ['$window', function($window) { return { set: function(key, value) { $window.localStorage[key] = value; }, get: function(key, defaultValue) { return $window.localStorage[key] || defaultValue; }, setObject: function(key, value) { $window.localStorage[key] = JSON.stringify(value); }, getObject: function(key) { return JSON.parse($window.localStorage[key] || '{}'); } } }]);
確ãã«ããã®åœ¢åŒã§äœ¿çšããŠãã100ïŒ ã®æ£åžžãªé åºã¯åŸãããŸããã§ããã 1ã€ã®è£œåããã¹ã±ããã«è¿œå ãããšãããã¹ãŠã¯åé¡ãããŸããã§ãããã2çªç®ã®ä»ã®è£œåãŸãã¯å¥ã®ã«ããŽãªãŒã®è£œåãå°çãããšããã«ãng-repeatã¯ãã¹ã±ããå ã®è£œåã®è¡šç€ºãåæ¢ããã³ã³ãœãŒã«ã«ãšã©ãŒã衚瀺ãããŸããïŒ
ãªããŒã¿ãŒã§ã®è€è£œã¯èš±å¯ãããŠããŸããã ããã©ãã¯åäœãåŒã䜿çšããŠãäžæã®ããŒãæå®ããŸãã
ãœãŒã¹[4]ã§ãã®ãšã©ãŒã®è§£æ±ºçãèŠã€ããŸããã ãã®åé¡ã¯ã$$é åã«hashKeyãè¿œå ãããããã§ãããããäœã§ãã©ãã§ããªããã¯ãŸã ããããŸãããããã¹ãŠãæ©èœãããããã«ãããåãé€ãå¿ èŠããããlocalStorageã§åäœãããã¡ã¯ããªã®æçµããŒãžã§ã³ã¯æ¬¡ã®ããã«ãªããŸãïŒ
function LocalStorageFactory($window) { return { set: function(key, value) { $window.localStorage[key] = value; }, get: function(key, defaultValue) { return $window.localStorage[key] || defaultValue; }, setObject: function(key, value) { $window.localStorage[key] = JSON.stringify(value, function (key, val) { if (key == '$$hashKey') { return undefined; } return val; }); }, getObject: function(key) { return JSON.parse($window.localStorage[key] || '{}'); }, remove: function(key){ $window.localStorage.removeItem(key); }, clear : function() { $window.localStorage.clear(); } } } angular.module('rollShop').factory('LocalStorageFactory', LocalStorageFactory);
ã³ãŒãã¯å°ããã2ã€ã®éããèŠã€ããããšã¯é£ãããªããšæããŸãã$$ hashKeyã確èªããããšã§ãéè€ãšã©ãŒãä¿®æ£ã§ããŸããã ããã§ããã¹ã±ãããµãŒãã¹ã¯é©åã«æ©èœããäœçœ®ãèšæ¶ããããéé¡ãåèšç®ãããããããšãã§ããŸããã ç§ã¯ä»¥äžã®ã³ãŒããäžããŸãïŒ
function CartsService(LocalStorageFactory) { var CartsService = {}; var CartData; if(LocalStorageFactory.getObject('carts').length > 0) { CartData = LocalStorageFactory.getObject('carts'); } else { CartData = []; } CartsService.addCart = function (item) { CartData.push({ id: item.id, num: item.quality || 1, title: item.title, price: item.price }); CartsService.update(); }; CartsService.update = function() { if(LocalStorageFactory.getObject('carts').length > 0) { LocalStorageFactory.remove('carts'); } LocalStorageFactory.setObject('carts',CartData); }; CartsService.getItemsCart = function () { return CartData; }; CartsService.removeItem = function (items, id) { items.splice(id, 1); CartsService.update(); }; CartsService.summary = function(dispatch) { var total = 0; var delivery = 0; angular.forEach(CartsService.getItemsCart(), function (item) { total += item.num * item.price; }); // return total + delivery; }; return CartsService; } angular.module('rollShop').factory('CartsService', CartsService);
å®ç§ã§ã¯ãããŸããããããã§ã以åãããåªããŠããŸãã
æ°ããã«ããŽãªãããŒãããéã®ã€ã³ã¿ãŒãã§ãŒã¹ã®å¿çæ§
ãµãŒããŒããéä¿¡ãããJSONããŒã¿ã®ééã¯10 kb以äžã§ããããµãŒããŒã«ããå¿çæéãšå¿çæéjsã¯äžè¬ã«ã巚倧ãªpingã䜿çšãããã°ãããã«ã ãã£ãã«ã€ã³ã¿ãŒãããã®å Žåããã¹ãŠã®ãªã¯ãšã¹ãã§ãŠãŒã¶ãŒããªããŒããŒã衚瀺ããã®ãçã«ããªã£ãŠããŸãã ã
ãã¡ããããããã³ã³ãããŒã©ãŒã«æž¡ãããšãã§ããŸããããã£ãšæ®éçãªãœãªã¥ãŒã·ã§ã³ãå¿ èŠã§ããããŸããã·ã³ãã«ã§ç°¡åãªãã®ãå¿ èŠã§ããã æåã¯ãAngularJSçšã®nProgress liteãã©ã°ã€ã³ã䜿çšããããšãèããŸããããããã«ç°¡åã«ããããšã決å®ããäŸãèŠã€ããŸãã[7]ã
function run($rootScope, $timeout) { $rootScope.layout = {}; $rootScope.layout.loading = false; $rootScope.$on('$routeChangeStart', function () { $timeout(function(){ $rootScope.layout.loading = true; }); }); $rootScope.$on('$routeChangeSuccess', function () { $timeout(function(){ $rootScope.layout.loading = false; }, 500); }); $rootScope.$on('$routeChangeError', function () { $timeout(function(){ $rootScope.layout.loading = false; }, 500); }); } angular.module('rollShop').run(run);
ããã§ãã€ãã³ãã®1ã€ãçºçãããšïŒã€ãã³ãã®ååããã¯ãã¹ãŠæããã ãšæããŸãïŒãããªããŒããŒã衚瀺/é衚瀺ã«ãªããŸãã
<div class="large-12 columns" ng-hide="!layout.loading"> <!-- , gif , , --> </div>
ããã§ãã¯ã©ã€ã¢ã³ãã¯ã«ããŽãªãããŒããããŠãããã©ãããèªèããã«ãã«ããŽãªã5åã¯ãªãã¯ããªããªããŸããã
ãããã«
éçºäžã«çããæ¬ ç¹ãä¿®æ£ããããšããŸããããäž»ãªç®æšã¯ãããŒã ããªããŠããæè¡ã®æèœãªäœ¿çšã«æ £ããããšã§ããã æ£çŽãªãšãããç§ã¯å€ãã®ä»äºã«æéãè²»ãããŸããããããã«å¯Ÿãããããªãå ±é ¬ãåãåããŸããã§ããããç§ã¯å€ãã®åã³ãåãåããŸããã ç§èªèº«ã¯ããã®ãããžã§ã¯ãã§åãåã£ããéã ãã§ãªããäœæ¥äžã«åŸãç¥èãšçµéšãé«ãè©äŸ¡ã§ãããããåŸç¶ã®ãã¹ãŠã®ãããžã§ã¯ããããæèœãªã¢ãããŒãã§è¡ããšçµè«ä»ããŸããã çµéšãšç¥èã¯åœŒãã®ä»äºã«èªããäžããä»äºã®è³ªãåäžãããããªããããããšãžã®æãäžããŸãã ãããŠãããããã¹ãŠãããªãã®ãã±ããã«ãéãªãã§ããªããæ®ãããšã¯ãããŸããã