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

Commit cd21216

Browse files
feat($compile): allow require to be an object
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
1 parent 3ffdf38 commit cd21216

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

src/ng/compile.js

+20-4
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,16 @@
271271
*
272272
* #### `require`
273273
* Require another directive and inject its controller as the fourth argument to the linking function. The
274-
* `require` takes a string name (or array of strings) of the directive(s) to pass in. If an array is used, the
275-
* injected argument will be an array in corresponding order. If no such directive can be
276-
* found, or if the directive does not have a controller, then an error is raised (unless no link function
277-
* is specified, in which case error checking is skipped). The name can be prefixed with:
274+
* `require` property can be a string, an array or an object:
275+
* * a **string** containing the name of the directive to pass to the linking function
276+
* * an **array** containing the names of directives to pass to the linking function. The argument passed to the
277+
* linking function will be an array of controllers in the same order as the names in the `require` property
278+
* * an **object** whose property values are the names of the directives to pass to the linking function. The argument
279+
* passed to the linking function will also be an object with matching keys, whose values will hold the corresponding
280+
* controllers.
281+
*
282+
* If no such directive(s) can be found, or if the directive does not have a controller, then an error is raised
283+
* (unless no link function is specified, in which case error checking is skipped). The name can be prefixed with:
278284
*
279285
* * (no prefix) - Locate the required controller on the current element. Throw an error if not found.
280286
* * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.
@@ -2308,6 +2314,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
23082314
for (var i = 0, ii = require.length; i < ii; i++) {
23092315
value[i] = getControllers(directiveName, require[i], $element, elementControllers);
23102316
}
2317+
} else if (isObject(require)) {
2318+
value = {};
2319+
forEach(require, function(controller, property) {
2320+
value[property] = getControllers(directiveName, controller, $element, elementControllers);
2321+
});
23112322
}
23122323

23132324
return value || null;
@@ -2414,6 +2425,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
24142425
removeControllerBindingWatches =
24152426
initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
24162427
}
2428+
2429+
if (isObject(controllerDirective.require) && !isArray(controllerDirective.require)) {
2430+
var controllers = getControllers(name, controllerDirective.require, $element, elementControllers);
2431+
console.log(controllers);
2432+
}
24172433
}
24182434

24192435
// Trigger the `$onInit` method on all controllers that have one

test/ng/compileSpec.js

+22
Original file line numberDiff line numberDiff line change
@@ -5716,6 +5716,28 @@ describe('$compile', function() {
57165716
});
57175717
});
57185718

5719+
it('should support multiple controllers as an object hash', function() {
5720+
module(function() {
5721+
directive('c1', valueFn({
5722+
controller: function() { this.name = 'c1'; }
5723+
}));
5724+
directive('c2', valueFn({
5725+
controller: function() { this.name = 'c2'; }
5726+
}));
5727+
directive('dep', function(log) {
5728+
return {
5729+
require: { myC1: '^c1', myC2: '^c2' },
5730+
link: function(scope, element, attrs, controllers) {
5731+
log('dep:' + controllers.myC1.name + '-' + controller.myC2.name);
5732+
}
5733+
};
5734+
});
5735+
});
5736+
inject(function(log, $compile, $rootScope) {
5737+
element = $compile('<div c1 c2><div dep></div></div>')($rootScope);
5738+
expect(log).toEqual('dep:c1-c2');
5739+
});
5740+
});
57195741

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

0 commit comments

Comments
 (0)