I'm trying to figure out where exactly the controller object gets published, when using the "controller as" syntax and instantiating the controller with $compile
. Here's a test I have:
describe('"Controller as" syntax', function() {
it('should work when controller is instantiated via $compile', function() {
var $injector = angular.injector(['ng', function($controllerProvider) {
$controllerProvider.register('DummyController', function() {
this.message = 'hello there';
});
}]);
var $compile = $injector.get('$compile');
var $rootScope = $injector.get('$rootScope');
var $scope = $rootScope.$new();
var view = $compile(
'<div ng-controller="DummyController as dummy">{{dummy.message}}</div>'
)($scope);
$rootScope.$apply();
// OK - The view is updated
expect(view.text()).toBe('hello there');
// FAIL - 'dummy' is not available on the $scope
expect($scope.dummy.message).toBe('hello there');
});
});
Please see the very last expectation. I expect dummy
to be available via $scope
, but it doesn't seem to be there. Am I wrong and it's not supposed to work like this?
I've also discovered that it's available via $scope.$$childTail
and $scope.$$childHead
:
// OK - 'dummy' is available here
expect($scope.$$childTail.dummy.message).toBe('hello there');
// OK - 'dummy' is available here
expect($scope.$$childHead.dummy.message).toBe('hello there');
Does it mean that there's a child scope created in my case, and dummy
gets only published on that child scope?
From $compile docs:
scope
If set to true, then a new scope will be created for this directive.
From ngController.js:
var ngControllerDirective = [function() {
return {
restrict: 'A',
scope: true,
controller: '@',
priority: 500
};
}];
So, it's as expected, my expectation was wrong. The only way to get to that dummy
property is via those $$...
things, which are not a part of public API.