diff --git a/src/ng/compile.js b/src/ng/compile.js
index 18ecce99dc92..7b9acc6cd026 100644
--- a/src/ng/compile.js
+++ b/src/ng/compile.js
@@ -536,14 +536,16 @@
* Testing Transclusion Directives}.
*
*
- * There are three kinds of transclusion depending upon whether you want to transclude just the contents of the
- * directive's element, the entire element or multiple parts of the element contents:
+ * There are four kinds of transclusion depending upon whether you want to transclude just the contents of the
+ * directive's element, the entire element, multiple parts of the element contents, or multiple parts dynamically:
*
* * `true` - transclude the content (i.e. the child nodes) of the directive's element.
* * `'element'` - transclude the whole of the directive's element including any directives on this
* element that defined at a lower priority than this directive. When used, the `template`
* property is ignored.
* * **`{...}` (an object hash):** - map elements of the content onto transclusion "slots" in the template.
+ * * `'dynamic'` - allow dynamic mulit-slot transclusion, by providing the slot configuration when using the component
+ * (in the transclusion-slot attrbiute)
*
* **Mult-slot transclusion** is declared by providing an object for the `transclude` property.
*
@@ -563,6 +565,13 @@
* `$transclude.isSlotFilled(slotName)` on the transclude function passed to the directive's link function and
* injectable into the directive's controller.
*
+ * **Dynamic mult-slot transclusion** is declared by using the 'dynamic' value on the component and then passing the
+ * transclusion slot configuration "later" (when actually using the component - via the transclude-slots attribute).
+ * Using this mode requires clear contract agreement between the component and the consumers, but it enables the
+ * possibility of arbitrary slots being used (in number and names).
+ *
+ * For an example of the dynamic mode usage, see {@link ngTransclude#dynamic-multi-slot-transclusion}.
+ *
*
* #### Transclusion Functions
*
@@ -2085,6 +2094,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
$template = jqLite(jqLiteClone(compileNode)).contents();
+ if (directiveValue === 'dynamic') {
+ if (!templateAttrs.transcludeSlots) {
+ throw $compileMinErr('reqdyn', 'Directive `{0}` requests dynamic transclusion slots but are not provided.', directive.name);
+ }
+ directiveValue = $parse(templateAttrs.transcludeSlots)();
+ }
+
if (isObject(directiveValue)) {
// We have transclusion slots,
diff --git a/src/ng/directive/ngTransclude.js b/src/ng/directive/ngTransclude.js
index c55537b2fdd0..f7555162587a 100644
--- a/src/ng/directive/ngTransclude.js
+++ b/src/ng/directive/ngTransclude.js
@@ -155,6 +155,56 @@
* expect(element(by.binding('text')).getText()).toEqual('TEXT');
* expect(element(by.css('.footer')).getText()).toEqual('Fallback Footer');
* });
+ *
+ *
+ *
+ * @example
+ * ### Dynamic multi-slot transclusion
+ * This example demonstrates using dynamic approach with multi-slot transclusion in a component directive.
+ * In this example, we use this mode to define a custom table component, while allowing the consumers to cleanly but
+ * optionally define their own cell templates:
+ * ' +
+ * '' +
+ * '
',
+ * scope: {
+ * transcludeSlots: '=',
+ * headers: '=',
+ * data: '='
+ * }
+ * };
+* });
* {{header.caption}} ' +
+ * '' +
+ * '' +
+ * '' +
+ * ' ' +
+ * '' +
+ * '' +
+ * ' ' +
+ * '