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

Commit

Permalink
feat(directive): support as instance syntax
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lgalfaso authored and mhevery committed Jul 31, 2013
1 parent aa5a162 commit b3777f2
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
7 changes: 7 additions & 0 deletions docs/content/guide/directive.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,13 @@ compiler}. The attributes are:
* `^` - Locate the required controller by searching the element's parents.
* `?^` - Attempt to locate the required controller by searching the element's parents, or return `null` if not found.

* `controllerAs` - Controller alias at the directive scope. An alias for the controller so it
can be referenced at the directive template. The directive needs to define a scope for this
configuration to be used. Useful in the case when directive is used as component.

* `require` - Require another controller be passed into current directive linking function. The
`require` takes a name of the directive controller to pass in. If no such controller can be
found an error is raised. The name can be prefixed with:

* `restrict` - String of subset of `EACM` which restricts the directive to a specific directive
declaration style. If omitted, the default (attributes only) is used.
Expand Down
13 changes: 11 additions & 2 deletions src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -961,16 +961,25 @@ function $CompileProvider($provide) {
$element: $element,
$attrs: attrs,
$transclude: boundTranscludeFn
};
}, controllerInstance;

controller = directive.controller;
if (controller == '@') {
controller = attrs[directive.name];
}

controllerInstance = $controller(controller, locals);
$element.data(
'$' + directive.name + 'Controller',
$controller(controller, locals));
controllerInstance);
if (directive.controllerAs) {
if (typeof locals.$scope !== 'object') {
throw new Error('Can not export controller as "' + identifier + '". ' +
'No scope object provided!');
}

locals.$scope[directive.controllerAs] = controllerInstance;
}
});
}

Expand Down
46 changes: 46 additions & 0 deletions test/ng/compileSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2244,6 +2244,52 @@ describe('$compile', function() {
});


iit('should support controllerAs', function() {
module(function() {
directive('main', function() {
return {
templateUrl: 'main.html',
transclude: true,
scope: {},
controller: function() {
this.name = 'lucas';
},
controllerAs: 'mainCtrl'
};
});
});
inject(function($templateCache, $compile, $rootScope) {
$templateCache.put('main.html', '<span>template:{{mainCtrl.name}} <div ng-transclude></div></span>');
element = $compile('<div main>transclude:{{mainCtrl.name}}</div>')($rootScope);
$rootScope.$apply();
expect(element.text()).toBe('template:lucas transclude:');
});
});


it('should support controller alias', function() {
module(function($controllerProvider) {
$controllerProvider.register('MainCtrl', function() {
this.name = 'lucas';
});
directive('main', function() {
return {
templateUrl: 'main.html',
scope: {},
controller: 'MainCtrl as mainCtrl'
};
});
});
inject(function($templateCache, $compile, $rootScope) {
$templateCache.put('main.html', '<span>{{mainCtrl.name}}</span>');
element = $compile('<div main></div>')($rootScope);
$rootScope.$apply();
expect(element.text()).toBe('lucas');
});
});



it('should require controller on parent element',function() {
module(function() {
directive('main', function(log) {
Expand Down

0 comments on commit b3777f2

Please sign in to comment.