diff options
| author | Lucas Galfasó | 2013-05-24 21:18:51 -0300 | 
|---|---|---|
| committer | Misko Hevery | 2013-07-31 10:30:58 -0700 | 
| commit | b3777f275c6bd2bd4a88963fd03828eb7cf3aca8 (patch) | |
| tree | 86d62c51db20647a59bb76912d8122cfcc0b7fe0 | |
| parent | aa5a16224bb4e19f44fafebaf04ece7665d5ad5b (diff) | |
| download | angular.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.ngdoc | 7 | ||||
| -rw-r--r-- | src/ng/compile.js | 13 | ||||
| -rwxr-xr-x | test/ng/compileSpec.js | 46 | 
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) { | 
