Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit b3777f2

Browse files
lgalfasomhevery
authored andcommitted
feat(directive): support as instance syntax
Support controller: 'MyController as my' syntax for directives which publishes the controller instance to the directive scope. Support controllerAs syntax to define an alias to the controller within the directive scope.
1 parent aa5a162 commit b3777f2

File tree

3 files changed

+64
-2
lines changed

3 files changed

+64
-2
lines changed

docs/content/guide/directive.ngdoc

+7
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,13 @@ compiler}. The attributes are:
401401
* `^` - Locate the required controller by searching the element's parents.
402402
* `?^` - Attempt to locate the required controller by searching the element's parents, or return `null` if not found.
403403

404+
* `controllerAs` - Controller alias at the directive scope. An alias for the controller so it
405+
can be referenced at the directive template. The directive needs to define a scope for this
406+
configuration to be used. Useful in the case when directive is used as component.
407+
408+
* `require` - Require another controller be passed into current directive linking function. The
409+
`require` takes a name of the directive controller to pass in. If no such controller can be
410+
found an error is raised. The name can be prefixed with:
404411

405412
* `restrict` - String of subset of `EACM` which restricts the directive to a specific directive
406413
declaration style. If omitted, the default (attributes only) is used.

src/ng/compile.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -961,16 +961,25 @@ function $CompileProvider($provide) {
961961
$element: $element,
962962
$attrs: attrs,
963963
$transclude: boundTranscludeFn
964-
};
964+
}, controllerInstance;
965965

966966
controller = directive.controller;
967967
if (controller == '@') {
968968
controller = attrs[directive.name];
969969
}
970970

971+
controllerInstance = $controller(controller, locals);
971972
$element.data(
972973
'$' + directive.name + 'Controller',
973-
$controller(controller, locals));
974+
controllerInstance);
975+
if (directive.controllerAs) {
976+
if (typeof locals.$scope !== 'object') {
977+
throw new Error('Can not export controller as "' + identifier + '". ' +
978+
'No scope object provided!');
979+
}
980+
981+
locals.$scope[directive.controllerAs] = controllerInstance;
982+
}
974983
});
975984
}
976985

test/ng/compileSpec.js

+46
Original file line numberDiff line numberDiff line change
@@ -2244,6 +2244,52 @@ describe('$compile', function() {
22442244
});
22452245

22462246

2247+
iit('should support controllerAs', function() {
2248+
module(function() {
2249+
directive('main', function() {
2250+
return {
2251+
templateUrl: 'main.html',
2252+
transclude: true,
2253+
scope: {},
2254+
controller: function() {
2255+
this.name = 'lucas';
2256+
},
2257+
controllerAs: 'mainCtrl'
2258+
};
2259+
});
2260+
});
2261+
inject(function($templateCache, $compile, $rootScope) {
2262+
$templateCache.put('main.html', '<span>template:{{mainCtrl.name}} <div ng-transclude></div></span>');
2263+
element = $compile('<div main>transclude:{{mainCtrl.name}}</div>')($rootScope);
2264+
$rootScope.$apply();
2265+
expect(element.text()).toBe('template:lucas transclude:');
2266+
});
2267+
});
2268+
2269+
2270+
it('should support controller alias', function() {
2271+
module(function($controllerProvider) {
2272+
$controllerProvider.register('MainCtrl', function() {
2273+
this.name = 'lucas';
2274+
});
2275+
directive('main', function() {
2276+
return {
2277+
templateUrl: 'main.html',
2278+
scope: {},
2279+
controller: 'MainCtrl as mainCtrl'
2280+
};
2281+
});
2282+
});
2283+
inject(function($templateCache, $compile, $rootScope) {
2284+
$templateCache.put('main.html', '<span>{{mainCtrl.name}}</span>');
2285+
element = $compile('<div main></div>')($rootScope);
2286+
$rootScope.$apply();
2287+
expect(element.text()).toBe('lucas');
2288+
});
2289+
});
2290+
2291+
2292+
22472293
it('should require controller on parent element',function() {
22482294
module(function() {
22492295
directive('main', function(log) {

0 commit comments

Comments
 (0)