mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-23 05:25:47 +00:00
feat($controller): support controller registration via $controllerProvider
It's now possible to register controllers as:
.register('MyCtrl', function($scope) { ... });
// or
.register('MyCtrl', ['$scope', function($scope) { ... });
Additionally a module loader shortcut api was added as well:
myModule.controller('MyCtr', function($scope) { ... });
This commit is contained in:
parent
4b8d926062
commit
d54dfecb00
5 changed files with 114 additions and 12 deletions
|
|
@ -167,13 +167,24 @@ function setupModuleLoader(window) {
|
||||||
* @ngdoc method
|
* @ngdoc method
|
||||||
* @name angular.Module#filter
|
* @name angular.Module#filter
|
||||||
* @methodOf angular.Module
|
* @methodOf angular.Module
|
||||||
* @param {string} name filter name
|
* @param {string} name Filter name.
|
||||||
* @param {Function} filterFactory Factory function for creating new instance of filter.
|
* @param {Function} filterFactory Factory function for creating new instance of filter.
|
||||||
* @description
|
* @description
|
||||||
* See {@link angular.module.ng.$filterProvider#register $filterProvider.register()}.
|
* See {@link angular.module.ng.$filterProvider#register $filterProvider.register()}.
|
||||||
*/
|
*/
|
||||||
filter: invokeLater('$filterProvider', 'register'),
|
filter: invokeLater('$filterProvider', 'register'),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.Module#controller
|
||||||
|
* @methodOf angular.Module
|
||||||
|
* @param {string} name Controller name.
|
||||||
|
* @param {Function} constructor Controller constructor function.
|
||||||
|
* @description
|
||||||
|
* See {@link angular.module.ng.$controllerProvider#register $controllerProvider.register()}.
|
||||||
|
*/
|
||||||
|
controller: invokeLater('$controllerProvider', 'register'),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngdoc method
|
* @ngdoc method
|
||||||
* @name angular.Module#directive
|
* @name angular.Module#directive
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,32 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc object
|
||||||
|
* @name angular.module.ng.$controllerProvider
|
||||||
|
* @description
|
||||||
|
* The {@link angular.module.ng.$controller $controller service} is used by Angular to create new
|
||||||
|
* controllers.
|
||||||
|
*
|
||||||
|
* This provider allows controller registration via the
|
||||||
|
* {@link angular.module.ng.$controllerProvider#register register} method.
|
||||||
|
*/
|
||||||
function $ControllerProvider() {
|
function $ControllerProvider() {
|
||||||
|
var controllers = {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc function
|
||||||
|
* @name angular.module.ng.$controllerProvider#register
|
||||||
|
* @methodOf angular.module.ng.$controllerProvider
|
||||||
|
* @param {string} name Controller name
|
||||||
|
* @param {Function|Array} constructor Controller constructor fn (optionally decorated with DI
|
||||||
|
* annotations in the array notation).
|
||||||
|
*/
|
||||||
|
this.register = function(name, constructor) {
|
||||||
|
controllers[name] = constructor;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
this.$get = ['$injector', '$window', function($injector, $window) {
|
this.$get = ['$injector', '$window', function($injector, $window) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -8,8 +34,14 @@ function $ControllerProvider() {
|
||||||
* @name angular.module.ng.$controller
|
* @name angular.module.ng.$controller
|
||||||
* @requires $injector
|
* @requires $injector
|
||||||
*
|
*
|
||||||
* @param {Function|string} Class Constructor function of a controller to instantiate, or
|
* @param {Function|string} constructor If called with a function then it's considered to be the
|
||||||
* expression to read from current scope or window.
|
* controller constructor function. Otherwise it's considered to be a string which is used
|
||||||
|
* to retrieve the controller constructor using the following steps:
|
||||||
|
*
|
||||||
|
* * check if a controller with given name is registered via `$controllerProvider`
|
||||||
|
* * check if evaluating the string on the current scope returns a constructor
|
||||||
|
* * check `window[constructor]` on the global `window` object
|
||||||
|
*
|
||||||
* @param {Object} locals Injection locals for Controller.
|
* @param {Object} locals Injection locals for Controller.
|
||||||
* @return {Object} Instance of given controller.
|
* @return {Object} Instance of given controller.
|
||||||
*
|
*
|
||||||
|
|
@ -20,14 +52,17 @@ function $ControllerProvider() {
|
||||||
* a service, so that one can override this service with {@link https://gist.github.com/1649788
|
* a service, so that one can override this service with {@link https://gist.github.com/1649788
|
||||||
* BC version}.
|
* BC version}.
|
||||||
*/
|
*/
|
||||||
return function(Class, locals) {
|
return function(constructor, locals) {
|
||||||
if(isString(Class)) {
|
if(isString(constructor)) {
|
||||||
var expression = Class;
|
var name = constructor;
|
||||||
Class = getter(locals.$scope, expression, true) || getter($window, expression, true);
|
constructor = controllers.hasOwnProperty(name)
|
||||||
assertArgFn(Class, expression);
|
? controllers[name]
|
||||||
|
: getter(locals.$scope, name, true) || getter($window, name, true);
|
||||||
|
|
||||||
|
assertArgFn(constructor, name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $injector.instantiate(Class, locals);
|
return $injector.instantiate(constructor, locals);
|
||||||
};
|
};
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,25 @@ describe('ng-view', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should support string controller declaration', function() {
|
||||||
|
var MyCtrl = jasmine.createSpy('MyCtrl');
|
||||||
|
|
||||||
|
module(function($controllerProvider, $routeProvider) {
|
||||||
|
$controllerProvider.register('MyCtrl', ['$scope', MyCtrl]);
|
||||||
|
$routeProvider.when('/foo', {controller: 'MyCtrl', template: '/tpl.html'});
|
||||||
|
});
|
||||||
|
|
||||||
|
inject(function($route, $location, $rootScope, $templateCache) {
|
||||||
|
$templateCache.put('/tpl.html', [200, '<div></div>', {}]);
|
||||||
|
$location.path('/foo');
|
||||||
|
$rootScope.$digest();
|
||||||
|
|
||||||
|
expect($route.current.controller).toBe('MyCtrl');
|
||||||
|
expect(MyCtrl).toHaveBeenCalledWith(element.contents().scope());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should load content via xhr when route changes', function() {
|
it('should load content via xhr when route changes', function() {
|
||||||
module(function($routeProvider) {
|
module(function($routeProvider) {
|
||||||
$routeProvider.when('/foo', {template: 'myUrl1'});
|
$routeProvider.when('/foo', {template: 'myUrl1'});
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ describe('module loader', function() {
|
||||||
value('k', 'v').
|
value('k', 'v').
|
||||||
filter('f', 'ff').
|
filter('f', 'ff').
|
||||||
directive('d', 'dd').
|
directive('d', 'dd').
|
||||||
|
controller('ctrl', 'ccc').
|
||||||
config('init2').
|
config('init2').
|
||||||
constant('abc', 123).
|
constant('abc', 123).
|
||||||
run('runBlock')).toBe(myModule);
|
run('runBlock')).toBe(myModule);
|
||||||
|
|
@ -52,6 +53,7 @@ describe('module loader', function() {
|
||||||
['$provide', 'value', ['k', 'v'] ],
|
['$provide', 'value', ['k', 'v'] ],
|
||||||
['$filterProvider', 'register', ['f', 'ff'] ],
|
['$filterProvider', 'register', ['f', 'ff'] ],
|
||||||
['$compileProvider', 'directive', ['d', 'dd'] ],
|
['$compileProvider', 'directive', ['d', 'dd'] ],
|
||||||
|
['$controllerProvider', 'register', ['ctrl', 'ccc']],
|
||||||
['$injector', 'invoke', ['init2'] ]
|
['$injector', 'invoke', ['init2'] ]
|
||||||
]);
|
]);
|
||||||
expect(myModule._runBlocks).toEqual(['runBlock']);
|
expect(myModule._runBlocks).toEqual(['runBlock']);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,47 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
describe('$controller', function() {
|
describe('$controller', function() {
|
||||||
var $controller;
|
var $controllerProvider, $controller;
|
||||||
|
|
||||||
beforeEach(inject(function($injector) {
|
beforeEach(module(function(_$controllerProvider_) {
|
||||||
$controller = $injector.get('$controller');
|
$controllerProvider = _$controllerProvider_;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
beforeEach(inject(function(_$controller_) {
|
||||||
|
$controller = _$controller_;
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
describe('provider', function() {
|
||||||
|
|
||||||
|
it('should allow registration of controllers', function() {
|
||||||
|
var FooCtrl = function($scope) { $scope.foo = 'bar' },
|
||||||
|
scope = {},
|
||||||
|
ctrl;
|
||||||
|
|
||||||
|
$controllerProvider.register('FooCtrl', FooCtrl);
|
||||||
|
ctrl = $controller('FooCtrl', {$scope: scope});
|
||||||
|
|
||||||
|
expect(scope.foo).toBe('bar');
|
||||||
|
expect(ctrl instanceof FooCtrl).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should allow registration of controllers annotated with arrays', function() {
|
||||||
|
var FooCtrl = function($scope) { $scope.foo = 'bar' },
|
||||||
|
scope = {},
|
||||||
|
ctrl;
|
||||||
|
|
||||||
|
$controllerProvider.register('FooCtrl', ['$scope', FooCtrl]);
|
||||||
|
ctrl = $controller('FooCtrl', {$scope: scope});
|
||||||
|
|
||||||
|
expect(scope.foo).toBe('bar');
|
||||||
|
expect(ctrl instanceof FooCtrl).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should return instance of given controller class', function() {
|
it('should return instance of given controller class', function() {
|
||||||
var MyClass = function() {},
|
var MyClass = function() {},
|
||||||
ctrl = $controller(MyClass);
|
ctrl = $controller(MyClass);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue