'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 scopethis
,$scope
interchangeable (angular setsthis
$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.
- when controller constructor function called,
$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.
- every controller has associated
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:
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.
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
Post a Comment