'this' vs $scope in AngularJS controllers -


in "create components" section of angularjs's homepage, there example:

controller: function($scope, $element) {   var panes = $scope.panes = [];   $scope.select = function(pane) {     angular.foreach(panes, function(pane) {       pane.selected = false;     });     pane.selected = true;   }   this.addpane = function(pane) {     if (panes.length == 0) $scope.select(pane);     panes.push(pane);   } } 

notice how select method added $scope, addpane method added this. if change $scope.addpane, code breaks.

the documentation says there in fact difference, doesn't mention difference is:

previous versions of angular (pre 1.0 rc) allowed use this interchangeably $scope method, no longer case. inside of methods defined on scope this , $scope interchangeable (angular sets this $scope), not otherwise inside controller constructor.

how this , $scope work in angularjs controllers?

"how this , $scope work in angularjs controllers?"

short answer:

  • this
    • when controller constructor function called, this controller.
    • when function defined on $scope object called, this "scope in effect when function called". may (or may not!) $scope function defined on. so, inside function, this , $scope may not same.
  • $scope
    • every controller has associated $scope object.
    • a controller (constructor) function responsible setting model properties , functions/behaviour on associated $scope.
    • only methods defined on $scope object (and parent scope objects, if prototypical inheritance in play) accessible html/view. e.g., ng-click, filters, etc.

long answer:

a controller function javascript constructor function. when constructor function executes (e.g., when view loads), this (i.e., "function context") set controller object. in "tabs" controller constructor function, when addpane function created

this.addpane = function(pane) { ... } 

it created on controller object, not on $scope. views cannot see addpane function -- have access functions defined on $scope. in other words, in html, won't work:

<a ng-click="addpane(newpane)">won't work</a> 

after "tabs" controller constructor function executes, have following:

after tabs controller constructor function

the dashed black line indicates prototypal inheritance -- isolate scope prototypically inherits scope. (it not prototypically inherit scope in effect directive encountered in html.)

now, pane directive's link function wants communicate tabs directive (which means needs affect tabs isolate $scope in way). events used, mechanism have pane directive require tabs controller. (there appears no mechanism pane directive require tabs $scope.)

so, begs question: if have access tabs controller, how access tabs isolate $scope (which want)?

well, red dotted line answer. addpane() function's "scope" (i'm referring javascript's function scope/closures here) gives function access tabs isolate $scope. i.e., addpane() has access "tabs isolatescope" in diagram above because of closure created when addpane() defined. (if instead defined addpane() on tabs $scope object, pane directive not have access function, , hence have no way communicate tabs $scope.)

to answer other part of question: how $scope work in controllers?:

within functions defined on $scope, this set "the $scope in effect where/when function called". suppose have following html:

<div ng-controller="parentctrl">    <a ng-click="logthisandscope()">log "this" , $scope</a> - parent scope    <div ng-controller="childctrl">       <a ng-click="logthisandscope()">log "this" , $scope</a> - child scope    </div> </div> 

and parentctrl (solely) has

$scope.logthisandscope = function() {     console.log(this, $scope) } 

clicking first link show this , $scope same, since "the scope in effect when function called" scope associated parentctrl.

clicking second link reveal this , $scope not same, since "the scope in effect when function called" scope associated childctrl. here, this set childctrl's $scope. inside method, $scope still parentctrl's $scope.

fiddle

i try not use this inside of function defined on $scope, becomes confusing $scope being affected, considering ng-repeat, ng-include, ng-switch, , directives can create own child scopes.


Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -