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

Commit

Permalink
feat($compile): allow require to be an object
Browse files Browse the repository at this point in the history
This provides an elegant alternative to the array form of the `require`
property but also helps to support binding of `require`d controllers
to directive controllers.

Closes #8401
Closes #13763
  • Loading branch information
petebacondarwin committed Jan 19, 2016
1 parent 3ffdf38 commit cd21216
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
24 changes: 20 additions & 4 deletions src/ng/compile.js
Expand Up @@ -271,10 +271,16 @@
*
* #### `require`
* Require another directive and inject its controller as the fourth argument to the linking function. The
* `require` takes a string name (or array of strings) of the directive(s) to pass in. If an array is used, the
* injected argument will be an array in corresponding order. If no such directive can be
* found, or if the directive does not have a controller, then an error is raised (unless no link function
* is specified, in which case error checking is skipped). The name can be prefixed with:
* `require` property can be a string, an array or an object:
* * a **string** containing the name of the directive to pass to the linking function
* * an **array** containing the names of directives to pass to the linking function. The argument passed to the
* linking function will be an array of controllers in the same order as the names in the `require` property
* * an **object** whose property values are the names of the directives to pass to the linking function. The argument
* passed to the linking function will also be an object with matching keys, whose values will hold the corresponding
* controllers.
*
* If no such directive(s) can be found, or if the directive does not have a controller, then an error is raised
* (unless no link function is specified, in which case error checking is skipped). The name can be prefixed with:
*
* * (no prefix) - Locate the required controller on the current element. Throw an error if not found.
* * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.
Expand Down Expand Up @@ -2308,6 +2314,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
for (var i = 0, ii = require.length; i < ii; i++) {
value[i] = getControllers(directiveName, require[i], $element, elementControllers);
}
} else if (isObject(require)) {
value = {};
forEach(require, function(controller, property) {
value[property] = getControllers(directiveName, controller, $element, elementControllers);
});
}

return value || null;
Expand Down Expand Up @@ -2414,6 +2425,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
removeControllerBindingWatches =
initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
}

if (isObject(controllerDirective.require) && !isArray(controllerDirective.require)) {
var controllers = getControllers(name, controllerDirective.require, $element, elementControllers);
console.log(controllers);
}
}

// Trigger the `$onInit` method on all controllers that have one
Expand Down
22 changes: 22 additions & 0 deletions test/ng/compileSpec.js
Expand Up @@ -5716,6 +5716,28 @@ describe('$compile', function() {
});
});

it('should support multiple controllers as an object hash', function() {
module(function() {
directive('c1', valueFn({
controller: function() { this.name = 'c1'; }
}));
directive('c2', valueFn({
controller: function() { this.name = 'c2'; }
}));
directive('dep', function(log) {
return {
require: { myC1: '^c1', myC2: '^c2' },
link: function(scope, element, attrs, controllers) {
log('dep:' + controllers.myC1.name + '-' + controller.myC2.name);
}
};
});
});
inject(function(log, $compile, $rootScope) {
element = $compile('<div c1 c2><div dep></div></div>')($rootScope);
expect(log).toEqual('dep:c1-c2');
});
});

it('should instantiate the controller just once when template/templateUrl', function() {
var syncCtrlSpy = jasmine.createSpy('sync controller'),
Expand Down

0 comments on commit cd21216

Please sign in to comment.