aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucas Galfasó2013-05-24 21:18:51 -0300
committerMisko Hevery2013-07-31 10:30:58 -0700
commitb3777f275c6bd2bd4a88963fd03828eb7cf3aca8 (patch)
tree86d62c51db20647a59bb76912d8122cfcc0b7fe0
parentaa5a16224bb4e19f44fafebaf04ece7665d5ad5b (diff)
downloadangular.js-b3777f275c6bd2bd4a88963fd03828eb7cf3aca8.tar.bz2
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.
-rw-r--r--docs/content/guide/directive.ngdoc7
-rw-r--r--src/ng/compile.js13
-rwxr-xr-xtest/ng/compileSpec.js46
3 files changed, 64 insertions, 2 deletions
diff --git a/docs/content/guide/directive.ngdoc b/docs/content/guide/directive.ngdoc
index 5e682d58..ea1c9ced 100644
--- a/docs/content/guide/directive.ngdoc
+++ b/docs/content/guide/directive.ngdoc
@@ -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.
diff --git a/src/ng/compile.js b/src/ng/compile.js
index 5b12883d..6aebe537 100644
--- a/src/ng/compile.js
+++ b/src/ng/compile.js
@@ -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;
+ }
});
}
diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js
index 45502b26..c2827559 100755
--- a/test/ng/compileSpec.js
+++ b/test/ng/compileSpec.js
@@ -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) {