|
237 | 237 | * as those elements need to created and cloned in a special way when they are defined outside their
|
238 | 238 | * usual containers (e.g. like `<svg>`).
|
239 | 239 | * * See also the `directive.templateNamespace` property.
|
240 |
| - * |
| 240 | + * The `$transclude` function has a property called `$slots`, which is a hash of slot names to slot transclusion |
| 241 | + * functions. If a slot was declared but not filled its value on the `$slots` object will be `null`. |
241 | 242 | *
|
242 | 243 | * #### `require`
|
243 | 244 | * Require another directive and inject its controller as the fourth argument to the linking function. The
|
|
347 | 348 | * * **`{...}` (an object hash):** - map elements of the content onto transclusion "slots" in the template.
|
348 | 349 | * See {@link ngTransclude} for more information.
|
349 | 350 | *
|
| 351 | + * Mult-slot transclusion is declared by providing an object for the `transclude` property. |
| 352 | + * This object is a map where the keys are the canonical name of HTML elements to match in the transcluded HTML, |
| 353 | + * and the values are the names of the slots. If the name is prefixed with a `?` then that slot is optional. |
| 354 | + * |
| 355 | + * The slots are made available as `$transclude.$slots` on the transclude function that is passed to the |
| 356 | + * linking functions as the fifth parameter, and can be injected into the directive controller. |
| 357 | + * |
350 | 358 | * #### `compile`
|
351 | 359 | *
|
352 | 360 | * ```js
|
@@ -2137,7 +2145,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
2137 | 2145 | // is later passed as `parentBoundTranscludeFn` to `publicLinkFn`
|
2138 | 2146 | transcludeFn = controllersBoundTransclude;
|
2139 | 2147 | transcludeFn.$$boundTransclude = boundTranscludeFn;
|
2140 |
| - transcludeFn.$$slots = boundTranscludeFn.$$slots; |
| 2148 | + // expose the slots on the `$transclude` function |
| 2149 | + transcludeFn.$slots = boundTranscludeFn.$$slots; |
2141 | 2150 | }
|
2142 | 2151 |
|
2143 | 2152 | if (controllerDirectives) {
|
@@ -2234,18 +2243,22 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
2234 | 2243 | futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element;
|
2235 | 2244 | }
|
2236 | 2245 | if (slotName) {
|
| 2246 | + // slotTranscludeFn can be one of three things: |
| 2247 | + // * a transclude function - a filled slot |
| 2248 | + // * `null` - an optional slot that was not filled |
| 2249 | + // * `undefined` - a slot that was not declared (i.e. invalid) |
2237 | 2250 | var slotTranscludeFn = boundTranscludeFn.$$slots[slotName];
|
2238 | 2251 | if (slotTranscludeFn) {
|
2239 | 2252 | return slotTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
|
2240 |
| - } |
2241 |
| - if (isUndefined(slotTranscludeFn)) { |
| 2253 | + } else if (isUndefined(slotTranscludeFn)) { |
2242 | 2254 | throw $compileMinErr('noslot',
|
2243 | 2255 | 'No parent directive that requires a transclusion with slot name "{0}". ' +
|
2244 | 2256 | 'Element: {1}',
|
2245 | 2257 | slotName, startingTag($element));
|
2246 | 2258 | }
|
| 2259 | + } else { |
| 2260 | + return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild); |
2247 | 2261 | }
|
2248 |
| - return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild); |
2249 | 2262 | }
|
2250 | 2263 | }
|
2251 | 2264 | }
|
|
0 commit comments