AngularJSã§èª°ããæåã«æããããšã¯ããã£ã¬ã¯ãã£ããDOMãšå¯Ÿè©±ããå¿ èŠããããšããããšã§ãã ãããŠäœããããåå¿è ã¯ã¹ã³ãŒãããã£ã¬ã¯ãã£ããã³ã³ãããŒã©ãŒéã®çžäºäœçšã®ããã»ã¹ã«æ··ä¹±ããŠããŸãã ãã®èšäºã§ã¯ãAngularã¢ããªã±ãŒã·ã§ã³ã®ã¹ã³ãŒããšã©ã€ããµã€ã¯ã«ã®è©³çŽ°ã調ã¹ãŸãã
次ã®å³ã§äœããããããªãå Žå-ãã®èšäºã¯ããªãã®ããã§ãã
ïŒãã®èšäºã§ã¯ãAngularJS 1.3.0ã«ã€ããŠèª¬æããŸãïŒ
AngularJSã¯ã¹ã³ãŒãã䜿çšããŠããã£ã¬ã¯ãã£ããšDOMã®éä¿¡ãæœè±¡åããŸãã ã³ã³ãããŒã©ãŒã®ã¬ãã«ã«ã¯ã¹ã³ãŒãããããŸãã ã¹ã³ãŒãã¯ãåçŽãªå€ãJavaScriptãªããžã§ã¯ãïŒPOJOïŒã§ãã ãããã¯ã1ã€ãŸãã¯2ã€ã®$æåãåã«ãããå éšãããããã£ã®æãè¿œå ããŸãã $$ãã¬ãã£ãã¯ã¹ãæã€ãã®ã¯ãã³ãŒãå ã§ããŸãé »ç¹ã«äœ¿çšããªãã§ãã ãããéåžžããããã®äœ¿çšã¯ã¢ããªã±ãŒã·ã§ã³ã®èª€è§£ã瀺ããŸãã
ã§ã¯ããããã®ã¹ã³ãŒãã¯ã©ã®ãããªãã®ã§ããïŒ
AngularJSã®å°éçšèªã§ã¯ãã¹ã³ãŒãã¯JSã³ãŒãã§ãããæå³ããããšãæå³ããŸããã éåžžãã¹ã³ãŒãã¯ãã³ã³ããã¹ããããŸããŸãªå€æ°ãªã©ãå«ãã³ãŒãã®ãããã¯ãšããŠç解ãããŸãã äŸïŒ
function eat (thing) { console.log(' ' + thing); } function nuts (peanut) { var hazelnut = 'hazelnut'; // function seeds () { var almond = 'almond'; // eat(hazelnut); // ! } // . }
ãã ãããããã¯AngularJSã§èšåãããŠããç¯å²ã§ã¯ãããŸããã
AngularJSã®ã¹ã³ãŒãç¶æ¿
AngularJSã®ã¹ã³ãŒããã³ã³ããã¹ãã§ãããAngularJSã®ç解ã®ã¿ã§ãã AngularJSã§ã¯ãã¹ã³ãŒãã¯èŠçŽ ãšãã®ãã¹ãŠã®åã«é¢é£ä»ããããŠãããèŠçŽ ã¯å¿ ãããã¹ã³ãŒãã«çŽæ¥é¢é£ããŠããããã§ã¯ãããŸããã èŠçŽ ã«ã¯ã3ã€ã®æ¹æ³ã®ããããã§ã¹ã³ãŒããå²ãåœãŠãããŸãã
1ã€ç®ã¯ãã³ã³ãããŒã©ãŒãŸãã¯ãã£ã¬ã¯ãã£ãã«ãã£ãŠèŠçŽ ã«ã¹ã³ãŒããäœæããããã©ããã§ãã
<nav ng-controller='menuCtrl'>
2çªç®-èŠçŽ ã«ã¹ã³ãŒãããªãå Žåã芪ããç¶æ¿ããŸã
<nav ng-controller='menuCtrl'> <a ng-click='navigate()'> !</a> <!-- also <nav>'s scope --> </nav>
第äž-èŠçŽ ãng-appã®äžéšã§ãªãå Žåãã©ã®ã¹ã³ãŒãã«ãå±ããªã
<head> <h1></h1> </head> <main ng-app='PonyDeli'> <nav ng-controller='menuCtrl'> <a ng-click='navigate()'> !</a> </nav> </main>
èŠçŽ ãã©ã®ã¹ã³ãŒãã«å±ããããç解ããã«ã¯ã3ã€ã®ã«ãŒã«ã䜿çšããŠãèŠçŽ ã®ããªãŒãå åŽããå€åŽã«åãã£ãŠèª¿ã¹ãŸãã æ°ããã¹ã³ãŒããäœæããŸããïŒ ãããã圌ã¯åœŒå¥³ãšã€ãªãã£ãŠããŸãã 圌ã«ã¯èŠªãããŸããïŒ èŠªã確èªããŸãã ng-appã®äžéšã§ãªãå Žå-ã¹ã³ãŒãã¯ãããŸããã
AngularJSã¹ã³ãŒãã®å éšããããã£ã®åŒã³åºã
ããã€ãã®å žåçãªããããã£ãèŠãŠã¿ãŸãããã ãããè¡ãã«ã¯ãChromeãéããŠãäœæ¥äžã®ã¢ããªã±ãŒã·ã§ã³ã«ç§»åããŸãã 次ã«ãéçºè ããŒã«ãéããŠèŠçŽ ã®ããããã£ã衚瀺ããŸãã $ 0ã¯ãèŠçŽ ããã«ã§æåŸã«éžæãããã¢ã€ãã ã«ã¢ã¯ã»ã¹ã§ããããšãç¥ã£ãŠããŸããïŒ $ 1-以åã«éžæããã¢ã€ãã ãªã© $ 0ãããé »ç¹ã«äœ¿çšããŸãã
angular.elementã¯ãåDOMèŠçŽ ãjQueryãŸãã¯jqLitââeã§ã©ããããŸãã ãã®åŸãscopeïŒïŒé¢æ°ã«ã¢ã¯ã»ã¹ããŠãèŠçŽ ã®ã¹ã³ãŒããè¿ããŸãã ããã0ãã«ãšçµã¿åãããŠãäžè¬çã«äœ¿çšãããã³ãã³ããååŸããŸãã
angular.element($0).scope()
jQueryã䜿çšãããŠããããã$ïŒ$ 0ïŒ.scopeïŒïŒãæ©èœããŸãã ããã§ãäžè¬çãªã¹ã³ãŒãã§äœ¿çšå¯èœãªããããã£ãã€ãŸã$ã§å§ãŸãããããã£ãèŠãŠã¿ãŸãããã
forïŒo in $ïŒ$ 0ïŒ.scopeïŒïŒïŒo [0] == '$' && console.logïŒoïŒ
AngularJSã¹ã³ãŒãå éšã®èª¿æ»
ãã®ã³ãã³ãã§è¡šç€ºãããããããã£ããªã¹ãããæ©èœå¥ã«ã°ã«ãŒãåããŸãã ç°¡åãªãã®ããå§ããŸãããã
$id $root $parent , null, scope == scope.$root $$childHead , null $$childTail , null $$prevSibling , null $$nextSibling , null
ãããã®ããããã£ã§ããã²ãŒãããã®ã¯äžäŸ¿ã§ãã $芪ã¯æã 圹ã«ç«ã€ããšããããŸããã芪èŠçŽ ã«ã¢ã¯ã»ã¹ããããã®ãã䟿å©ãªæ¹æ³ãåžžã«ãããŸãã ããšãã°ãã€ãã³ãã®äœ¿çšã¯ããªã¹ãã®æ¬¡ã®éšåã§æ€èšããŸãã
AngularJSã€ãã³ãã¹ã³ãŒãã³ã°ã¢ãã«
次ã®ããããã£ã¯ãã€ãã³ããèå¥ããŠãµãã¹ã¯ã©ã€ãããã®ã«åœ¹ç«ã¡ãŸãã
$$listeners , $on(evt, fn) fn evt $emit(evt, args) evt, , $parent, $rootScope $broadcast(evt, args) evt, ,
èµ·åããããšãã€ãã³ããã³ãã©ã¯ã€ãã³ããªããžã§ã¯ããšã$ emitãŸãã¯$ broadcastã«æž¡ãããåŒæ°ãåãåããŸãã ã€ãã³ãã¯ã©ã®ããã«äœ¿çšã§ããŸããïŒ
ãã£ã¬ã¯ãã£ãã¯ãããã䜿çšããŠéèŠãªã€ãã³ããå ±åã§ããŸãã ãã®äŸã§ã¯ããã¿ã³ãæŒããšã€ãã³ããçºçããŸãã
angular.module('PonyDeli').directive('food', function () { return { scope: { // type: '=type' }, template: '<button ng-click="eat()"> {{type}}!</button>', link: function (scope, element, attrs) { scope.eat = function () { letThemHaveIt(); scope.$emit('food.order, scope.type, element); }; function letThemHaveIt () { // UI } } }; });
åå空éã€ãã³ããèšå®ããŸãã ããã«ãããååã亀差ããã®ãé²ããã€ãã³ãã®çºä¿¡å ãŸãã¯è³ŒèªããŠããã€ãã³ããç解ããã®ã«åœ¹ç«ã¡ãŸãã åæã«èå³ããããMixpanelãä»ããŠé£åã®ãã¹ãŠã®ã¯ãªãã¯ã远跡ãããšããŸãã ã³ã³ãããŒã©ãŸãã¯ãã£ã¬ã¯ãã£ããæ£ããã代ããã«ãã¯ãªãã¯ã远跡ããããã®å¥åã®ãã£ã¬ã¯ãã£ããäœæã§ããŸããããã¯ãããèªäœãå¥åã®ãã®ã«ãªããŸãã
angular.module('PonyDeli').directive('foodTracker', function (mixpanelService) { return { link: function (scope, element, attrs) { scope.$on('food.order, function (e, type) { mixpanelService.track('food-eater', type); }); } }; });
ããã§ã¯ããµãŒãã¹ã®å®è£ ã¯éèŠã§ã¯ãããŸãããMixpanelã¯ã©ã€ã¢ã³ãAPIã®ã©ãããŒãšããŠæ©èœããã ãã§ãã HTMLã¯æ¬¡ã®ããã«ãªããå¿ èŠãªãã¹ãŠã®çš®é¡ã®é£åãå«ãå¥ã®ã³ã³ãããŒã©ãŒãè¿œå ããŸãã ãã®äŸãå®äºããããã«ãng-repeatãè¿œå ããŠãã³ãŒããã³ããŒããã«é£ã¹ç©ããªã¹ãã§ããããã«ããŸãã foodTypesã®ãµã€ã¯ã«ã§ãããã衚瀺ããã ãã§ãfoodCtrlã®ã¹ã³ãŒãã§äœ¿çšã§ããŸãã
<ul ng-app='PonyDeli' ng-controller='foodCtrl' food-tracker> <li food type='type' ng-repeat='type in foodTypes'></li> </ul> angular.module('PonyDeli').controller('foodCtrl', function ($scope) { $scope.foodTypes = ['', '', '']; });
å®éã®äŸã«ã€ããŠã¯ã CodePenãåç §ããŠãã ãã ã
ããããäœããæ¥ç¶ã§ããã€ãã³ããå¿ èŠã§ããïŒ ååãªãµãŒãã¹ã¯ãããŸããïŒ ãã®å Žåãããªãã¯ããããããšãã§ããŸãã food.orderã«ãµãã¹ã¯ã©ã€ãããä»ã®ãŠãŒã¶ãŒãäºåã«ããããªããããã€ãã³ããå¿ èŠã§ãããšäž»åŒµã§ããŸããã€ãŸããã€ãã³ãã®äœ¿çšã¯ã¢ããªã±ãŒã·ã§ã³éçºã®èŠ³ç¹ããããå ãèŠéããŠããŸãã ãŸããé£å远跡ãã£ã¬ã¯ãã£ãã¯å¿ èŠãããŸãããããã¯ãDOMãšå¯Ÿè©±ãããã€ãã³ããåŸ æ©ããã ãã§ããããããµãŒãã¹ã«çœ®ãæããããšãã§ããããã§ãã
ãã®å Žåããããã¯æ£ããã³ã¡ã³ãã§ãã ããããä»ã®ã³ã³ããŒãã³ããfood.orderãšéä¿¡ããå¿ èŠãããå Žåãã€ãã³ãã®å¿ èŠæ§ãæããã«ãªããŸãã å®éã«ã¯ãå¯èŠæ§ã®ããã€ãã®é åãæ¥ç¶ããå¿ èŠãããå Žåãã€ãã³ããæã圹ç«ã¡ãŸãã
åãã¬ãã«ã®èŠçŽ ã¯éåžžãçžäºã«éä¿¡ããã®ãå°é£ã§ãããéåžžã¯èŠªãéããŠéä¿¡ããŸãã çµæãšããŠãããã¯$ rootScopeããã®ãããŒããã£ã¹ããã£ã¹ãã£ã³ã°ã«å€æããããããå¿ èŠãšãããã¹ãŠã®äººãèãããšãã§ããŸãã
<body ng-app='PonyDeli'> <div ng-controller='foodCtrl'> <ul food-tracker> <li food type='type' ng-repeat='type in foodTypes'></li> </ul> <button ng-click='deliver()'> !</button> </div> <div ng-controller='deliveryCtrl'> <span ng-show='received'> , . </span> </div> </body>
angular.module('PonyDeli').controller('foodCtrl', function ($rootScope) { $scope.foodTypes = ['', '', '']; $scope.deliver = function (req) { $rootScope.$broadcast('delivery.request', req); }; }); angular.module('PonyDeli').controller('deliveryCtrl', function ($scope) { $scope.$on('delivery.request', function (e, req) { $scope.received = true; // }); });
CodePenã®äœæ¥ãã芧ãã ãã ã
ç§ã¯ãã€ãã³ãããµãŒãã¹ã«å¿ããŠãã¥ãŒãå€åãããšäºæ³ãããå Žåãã€ãã³ãã䜿çšãããã¹ãã ãšèšããŸã-ãã¥ãŒãå€åããªãå Žåã
$ rootScopeãä»ããŠéä¿¡ãã2ã€ã®ã³ã³ããŒãã³ããããå Žåã$ rootScopeã$ Emitãš$ rootScopeã$ãããŒããã£ã¹ãã®ä»£ããã«$ Onã䜿çšããããšããå§ãããŸãã ãã®åŸãã€ãã³ãã¯$ rootScopeã$$ãªã¹ããŒéã§ã®ã¿é åžããããã®ã€ãã³ãã®ãã³ãã©ãŒãæããªããã¹ãŠã®$ rootScopeåããŒããæž¡ãæéãç¡é§ã«ããŸããã ãã®äŸã§ã¯ããµãŒãã¹ã¯ç¹å®ã®ã¹ã³ãŒãã«éå®ããããã€ãã³ãã«$ rootScopeã䜿çšããŸãã ã€ãã³ãããªãã¹ã³ããããã«ãµãã¹ã¯ã©ã€ããããµãã¹ã¯ã©ã€ãã¡ãœãããæäŸããŸãã
angular.module('PonyDeli').factory("notificationService", function ($rootScope) { function notify (data) { $rootScope.$emit("notificationService.update", data); } function listen (fn) { $rootScope.$on("notificationService.update", function (e, data) { fn(data); }); } // , function load () { setInterval(notify.bind(null, '- !'), 1000); } return { subscribe: listen, load: load }; });
ãŸããããã¯CodePenã«ããããŸãã
ãã€ãžã§ã¹ã
AngularJSããŒã¿ãã€ã³ãã£ã³ã°ã¯ã å€æŽã远跡ããŠã€ãã³ããçºçãããã«ãŒããä»ããŠæ©èœããŸãã $ãã€ãžã§ã¹ãã«ãŒãã«ã¯ããã€ãã®æ¹æ³ããããŸãã æåã¯ã¹ã³ãŒãã§ã$ãã€ãžã§ã¹ãã¯ãçŸåšã®ã¹ã³ãŒããšåé åã®å€æŽãååž°çã«ãã€ãžã§ã¹ãããŸãã
$digest() $$phase â [null, '$apply', '$digest']
ãã§ã«ãã€ãžã§ã¹ããã§ãŒãºã«ããå Žåã¯ãã€ãžã§ã¹ããå®è¡ããªãã§ãã ãã-ããã¯äºæž¬ã§ããªãçµæã«ã€ãªãããŸãã ããã¥ã¡ã³ãã®ãã€ãžã§ã¹ãã«ã€ããŠäœãèšãããŠããŸãã ïŒ
çŸåšã®ã¹ã³ãŒããšãã®åé åã®ãã¹ãŠã®ãŠã©ããã£ãŒãéå§ããŸãã ãªãã¶ãŒããŒã®ãªã¹ããŒã¯ã¢ãã«ãå€æŽã§ããããã$ digestïŒïŒã¯ããªã¹ããŒã®å®è¡ãåæ¢ãããŸã§ãªãã¶ãŒããŒãåŒã³åºããŸãã ããã«ãããç¡éã«ãŒããçºçããå¯èœæ§ããããŸãã ãããã£ãŠãé¢æ°ã10ãè¶ ããå Žåããå埩ã®æ倧æ°ã«éããŸããããšãããšã©ãŒãã¹ããŒãããŸãã
éåžžã$ digestïŒïŒã¯ã³ã³ãããŒã©ãŒãŸãã¯ãã£ã¬ã¯ãã£ãããçŽæ¥åŒã³åºãããŸããã $ applyïŒïŒãåŒã³åºãå¿ èŠããããŸãïŒéåžžãããã¯ãã£ã¬ã¯ãã£ãå ããè¡ãããŸãïŒãããèªäœã$ digestïŒïŒãåŒã³åºããŸãã
ããã¯ã$ãã€ãžã§ã¹ãããã¹ãŠã®ãªãã¶ãŒããŒãåŠçãããã®åŸãå®è¡ãåæ¢ãããŸã§åã®ãªãã¶ãŒããŒã«ãã£ãŠåŒã³åºããããã¹ãŠã®ãªãã¶ãŒããŒãåŠçããããšãæå³ããŸãã 2ã€ã®è³ªåãæ®ã£ãŠããŸãã
-ãªãã¶ãŒããŒã¯èª°ã§ããïŒ
-$ãã€ãžã§ã¹ãã®åå ã¯äœã§ããïŒ
ããªãã¶ãŒããŒããšã¯äœããç¥ã£ãŠããŠãã¹ã³ãŒãã䜿çšããŠããå ŽåããããŸãã $$ watchersããããã£ã«ã¯ãã¹ã³ãŒãã®ãã¹ãŠã®ãªãã¶ãŒããŒãå«ãŸããŸãã
$watch(watchExp, listener, objectEquality) $watchCollection $$watchers
ãªãã¶ãŒããŒã¯ãAngularJSã®æãéèŠãªåŽé¢ã§ãããããŒã¿ãã€ã³ãã£ã³ã°ãæ£ããæ©èœããããã«ã¯ãåŒã³åºããéå§ããå¿ èŠããããŸãã äŸïŒ
<body ng-app='PonyDeli'> <ul ng-controller='foodCtrl'> <li ng-bind='prop'></li> <li ng-bind='dependency'></li> </ul> </body>
angular.module('PonyDeli').controller('foodCtrl', function ($scope) { $scope.prop = ' '; $scope.dependency = ' !'; $scope.$watch('prop', function (value) { $scope.dependency = 'prop "' + value + '"! '; }); setTimeout(function () { $scope.prop = ' '; }, 1000); });
ãããã£ãŠããåæå€ãããããHTMLã®2è¡ç®ããprop contains "another value"ãã«å€æŽãããããšãäºæ³ãããŸãã ãŸããããã§ããïŒ ãããŠãæåã®è¡ããå¥ã®å€ãã«å€ããããšãäºæ³ãããŸãã ãªã圌女ã¯å€ãããªãã®ã§ããïŒ
HTMLã§äœæãããã®ã®å€ãã¯ãçµæãšããŠãªãã¶ãŒããŒãäœæããŸãã ãã®å Žåãång-bindãã£ã¬ã¯ãã£ãã¯ããããã£ã®ãªãã¶ãŒããŒãäœæããŸãã ããããã£ãšäŸåé¢ä¿ãå€æŽããããšãHTMLã§æŽæ°ãããŸãã ãããã£ãŠãã³ãŒãã«ã¯3ã€ã®ãªãã¶ãŒããŒããããŸãïŒång-bindã«1ã€ãã³ã³ãããŒã©ãŒã«1ã€ïŒã ã¿ã€ã ã¢ãŠãåŸã«ããããã£ãæŽæ°ãããããšãAngularJSã¯ã©ã®ããã«ç¥ãã®ã§ããïŒ ã¿ã€ããŒã³ãŒã«ããã¯ã«ãã€ãžã§ã¹ãã³ãŒã«ãè¿œå ãããšããã®ããšãæãåºãããããšãã§ããŸãã
setTimeout(function () { $scope.prop = ' '; $scope.$digest(); }, 1000);
CodePenã«2ã€ã®äŸãä¿åããŸããã1ã€ã¯$ digestãªã㧠ããã1ã€ã¯ããä»ãã§ãã ããããããæ£ããæ¹æ³ã¯ãsetTimeoutã®ä»£ããã«$ã¿ã€ã ã¢ãŠããµãŒãã¹ã䜿çšããããšã§ãã ãšã©ãŒåŠçãæäŸãã$ applyïŒïŒãå®è¡ããŸãã
$timeout(function () { $scope.prop = ' '; }, 1000);
$apply(expr) , $digest $rootScope
ããŠã$ãã€ãžã§ã¹ããåŒã³åºã人ã«ã€ããŠã ãããã®é¢æ°ã¯ãã³ãŒãå ã®æŠç¥çãªå Žæã§AngularJSèªäœã«ãã£ãŠåŒã³åºãããŸãã ãããã¯ãçŽæ¥åŒã³åºãããšãã$ applyïŒïŒãåŒã³åºãããšã«ãã£ãŠåŒã³åºãããšãã§ããŸãã ã»ãšãã©ã®ãã¬ãŒã ã¯ãŒã¯ãã£ã¬ã¯ãã£ãã¯ããããã®é¢æ°ãåŒã³åºããŸãã ãããã¯ãªãã¶ãŒããŒãåŒã³åºãããªãã¶ãŒããŒã¯ã€ã³ã¿ãŒãã§ãŒã¹ãæŽæ°ããŸãã
ã¹ã³ãŒãå ã«ãã$ãã€ãžã§ã¹ãã«ãŒãã«é¢é£ä»ããããŠããããããã£ã®ãªã¹ããèŠãŠã¿ãŸãããã
$eval(expression, locals) $evalAsync(expression) $$asyncQueue , digest $$postDigest(fn) fn digest $$postDigestQueue $$postDigest(fn)
ã©ã€ããµã€ã¯ã«ãåŠçããäžè¬çã«å éšç®çã«äœ¿çšãããã¹ã³ãŒãã®ããããã£ãããã€ã次ã«ç€ºããŸãã ãã ããå Žåã«ãã£ãŠã¯ã$ newã䜿çšããŠæ°ããã¹ã³ãŒããäœæããå¿ èŠããããŸãã
$$isolateBindings ( , { options: '@megaOptions' } $new(isolate) , $destroy . $$destroyed
èšäºã®ç¬¬2éšã§ã¯ããã£ã¬ã¯ãã£ããåé¢ã¹ã³ãŒãããã©ã³ã¹ã¯ã«ãŒãžã§ã³ããã€ã³ããããé¢æ°ãã³ã³ãã€ã©ãŒããã£ã¬ã¯ãã£ãã³ã³ãããŒã©ãŒãªã©ã«ã€ããŠèª¬æããŸãã