mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +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
|
||||
* @name angular.Module#filter
|
||||
* @methodOf angular.Module
|
||||
* @param {string} name filter name
|
||||
* @param {string} name Filter name.
|
||||
* @param {Function} filterFactory Factory function for creating new instance of filter.
|
||||
* @description
|
||||
* See {@link angular.module.ng.$filterProvider#register $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
|
||||
* @name angular.Module#directive
|
||||
|
|
|
|||
|
|
@ -1,6 +1,32 @@
|
|||
'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() {
|
||||
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) {
|
||||
|
||||
/**
|
||||
|
|
@ -8,8 +34,14 @@ function $ControllerProvider() {
|
|||
* @name angular.module.ng.$controller
|
||||
* @requires $injector
|
||||
*
|
||||
* @param {Function|string} Class Constructor function of a controller to instantiate, or
|
||||
* expression to read from current scope or window.
|
||||
* @param {Function|string} constructor If called with a function then it's considered to be the
|
||||
* 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.
|
||||
* @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
|
||||
* BC version}.
|
||||
*/
|
||||
return function(Class, locals) {
|
||||
if(isString(Class)) {
|
||||
var expression = Class;
|
||||
Class = getter(locals.$scope, expression, true) || getter($window, expression, true);
|
||||
assertArgFn(Class, expression);
|
||||
return function(constructor, locals) {
|
||||
if(isString(constructor)) {
|
||||
var name = constructor;
|
||||
constructor = controllers.hasOwnProperty(name)
|
||||
? 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() {
|
||||
module(function($routeProvider) {
|
||||
$routeProvider.when('/foo', {template: 'myUrl1'});
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ describe('module loader', function() {
|
|||
value('k', 'v').
|
||||
filter('f', 'ff').
|
||||
directive('d', 'dd').
|
||||
controller('ctrl', 'ccc').
|
||||
config('init2').
|
||||
constant('abc', 123).
|
||||
run('runBlock')).toBe(myModule);
|
||||
|
|
@ -52,6 +53,7 @@ describe('module loader', function() {
|
|||
['$provide', 'value', ['k', 'v'] ],
|
||||
['$filterProvider', 'register', ['f', 'ff'] ],
|
||||
['$compileProvider', 'directive', ['d', 'dd'] ],
|
||||
['$controllerProvider', 'register', ['ctrl', 'ccc']],
|
||||
['$injector', 'invoke', ['init2'] ]
|
||||
]);
|
||||
expect(myModule._runBlocks).toEqual(['runBlock']);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,47 @@
|
|||
'use strict';
|
||||
|
||||
describe('$controller', function() {
|
||||
var $controller;
|
||||
var $controllerProvider, $controller;
|
||||
|
||||
beforeEach(inject(function($injector) {
|
||||
$controller = $injector.get('$controller');
|
||||
beforeEach(module(function(_$controllerProvider_) {
|
||||
$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() {
|
||||
var MyClass = function() {},
|
||||
ctrl = $controller(MyClass);
|
||||
|
|
|
|||
Loading…
Reference in a new issue