diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/plnkr.json b/public/docs/_examples/cb-dynamic-component-loader/ts/plnkr.json
new file mode 100644
index 0000000000..c43fb15c12
--- /dev/null
+++ b/public/docs/_examples/cb-dynamic-component-loader/ts/plnkr.json
@@ -0,0 +1,9 @@
+{
+ "description": "Dynamic Component Loader",
+ "basePath": "src/",
+ "files":[
+ "!**/*.d.ts",
+ "!**/*.js"
+ ],
+ "tags":["cookbook component"]
+}
diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad-banner.component.ts b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad-banner.component.ts
index 293d31dea9..8489fce5b2 100644
--- a/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad-banner.component.ts
+++ b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad-banner.component.ts
@@ -11,11 +11,12 @@ import { AdComponent } from './ad.component';
template: `
Advertisements
-
+
`
- // #enddocregion ad-host
+ // #enddocregion ad-host
})
+// #docregion class
export class AdBannerComponent implements AfterViewInit, OnDestroy {
@Input() ads: AdItem[];
currentAddIndex: number = -1;
@@ -53,3 +54,4 @@ export class AdBannerComponent implements AfterViewInit, OnDestroy {
}, 3000);
}
}
+// #enddocregion class
diff --git a/public/docs/ts/latest/cookbook/dynamic-component-loader.jade b/public/docs/ts/latest/cookbook/dynamic-component-loader.jade
index feace0d526..583e8e1e26 100644
--- a/public/docs/ts/latest/cookbook/dynamic-component-loader.jade
+++ b/public/docs/ts/latest/cookbook/dynamic-component-loader.jade
@@ -3,107 +3,158 @@ include ../_util-fns
:marked
Component templates are not always fixed. An application may need to load new components at runtime.
- In this cookbook we show how to use `ComponentFactoryResolver` to add components dynamically.
+ This cookbook shows you how to use `ComponentFactoryResolver` to add components dynamically.
:marked
- ## Table of contents
+ # Contents
- [Dynamic Component Loading](#dynamic-loading)
+ * [Dynamic component loading](#dynamic-loading)
+ * [The directive](#directive)
+ * [Loading components](#loading-components)
- [Where to load the component](#where-to-load)
+ * [Resolving Components](#resolving-components)
+ * [Selector References](#selector-references)
- [Loading components](#loading-components)
+ * [A common _AdComponent_ interface](#common-interface)
+ * [Final ad banner](#final-ad-banner)
+
+:marked
+ See the
+ of the code in this cookbook.
.l-main-section
:marked
- ## Dynamic Component Loading
+ ## Dynamic component loading
- The following example shows how to build a dynamic ad banner.
-
- The hero agency is planning an ad campaign with several different ads cycling through the banner.
+ The following example shows how to build a dynamic ad banner.
- New ad components are added frequently by several different teams. This makes it impractical to use a template with a static component structure.
-
- Instead we need a way to load a new component without a fixed reference to the component in the ad banner's template.
+ The hero agency is planning an ad campaign with several different
+ ads cycling through the banner. New ad components are added
+ frequently by several different teams. This makes it impractical
+ to use a template with a static component structure.
- Angular comes with its own API for loading components dynamically. In the following sections you will learn how to use it.
+ Instead, you need a way to load a new component without a fixed
+ reference to the component in the ad banner's template.
+
+ Angular comes with its own API for loading components dynamically.
.l-main-section
-
+
:marked
- ## Where to load the component
+ ## The directive
- Before components can be added we have to define an anchor point to mark where components can be inserted dynamically.
+ Before you can add components you have to define an anchor point
+ to tell Angular where to insert components.
- The ad banner uses a helper directive called `AdDirective` to mark valid insertion points in the template.
+ The ad banner uses a helper directive called `AdDirective` to
+ mark valid insertion points in the template.
+makeExample('cb-dynamic-component-loader/ts/src/app/ad.directive.ts',null,'src/app/ad.directive.ts')(format='.')
:marked
- `AdDirective` injects `ViewContainerRef` to gain access to the view container of the element that will become the host of the dynamically added component.
-
+ `AdDirective` injects `ViewContainerRef` to gain access to the view
+ container of the element that will host the dynamically added component.
+
+ In the `@Directive` decorator, notice the selector name, `ad-host`;
+ that's what you use to apply the directive to the element.
+ The next section shows you how.
+
.l-main-section
:marked
## Loading components
- The next step is to implement the ad banner. Most of the implementation is in `AdBannerComponent`.
+ Most of the ad banner implementation is in `ad-banner.component.ts`.
+ To keep things simple in this example, the HTML is in the `@Component`
+ decorator's `template` property as a template string.
- We start by adding a `template` element with the `AdDirective` directive applied.
-
-+makeTabs(
- `cb-dynamic-component-loader/ts/src/app/ad-banner.component.ts,
- cb-dynamic-component-loader/ts/src/app/ad.service.ts,
- cb-dynamic-component-loader/ts/src/app/ad-item.ts,
- cb-dynamic-component-loader/ts/src/app/app.module.ts,
- cb-dynamic-component-loader/ts/src/app/app.component.ts`,
- null,
- `ad-banner.component.ts,
- ad.service.ts,
- ad-item.ts,
- app.module.ts,
- app.component`
-)
-
-:marked
- The `template` element decorated with the `ad-host` directive marks where dynamically loaded components will be added.
-
- Using a `template` element is recommended since it doesn't render any additional output.
+ The `` element is where you apply the directive you just made.
+ To apply the `AdDirective`, recall the selector from `ad.directive.ts`,
+ `ad-host`. Apply that to `` without the square brackets. Now Angular knows
+ where to dynamically load components.
+makeExample('cb-dynamic-component-loader/ts/src/app/ad-banner.component.ts', 'ad-host' ,'src/app/ad-banner.component.ts (template)')(format='.')
:marked
- ### Resolving Components
+ The `` element is a good choice for dynamic components
+ because it doesn't render any additional output.
- `AdBanner` takes an array of `AdItem` objects as input. `AdItem` objects specify the type of component to load and any data to bind to the component.
+a#resolving-components
+:marked
+ ### Resolving components
- The ad components making up the ad campaign are returned from `AdService`.
-
- Passing an array of components to `AdBannerComponent` allows for a dynamic list of ads without static elements in the template.
+ Take a closer look at the methods in `ad-banner.component.ts`.
- `AdBannerComponent` cycles through the array of `AdItems` and loads the corresponding components on an interval. Every 3 seconds a new component is loaded.
+ `AdBannerComponent` takes an array of `AdItem` objects as input,
+ which ultimately comes from `AdService`. `AdItem` objects specify
+ the type of component to load and any data to bind to the
+ component.`AdService` returns the actual ads making up the ad campaign.
- `ComponentFactoryResolver` is used to resolve a `ComponentFactory` for each specific component. The component factory is need to create an instance of the component.
+ Passing an array of components to `AdBannerComponent` allows for a
+ dynamic list of ads without static elements in the template.
- `ComponentFactories` are generated by the Angular compiler.
-
- Generally the compiler will generate a component factory for any component referenced in a template.
-
- With dynamically loaded components there are no selector references in the templates since components are loaded at runtime. In order to ensure that the compiler will still generate a factory, dynamically loaded components have to be added to their `NgModule`'s `entryComponents` array.
+ With its `getAds()` method, `AdBannerComponent` cycles through the array of `AdItems`
+ and loads a new component every 3 seconds by calling `loadComponent()`.
-+makeExample('cb-dynamic-component-loader/ts/src/app/app.module.ts', 'entry-components' ,'src/app/app.module.ts (entry components)')(format='.')
++makeExample('cb-dynamic-component-loader/ts/src/app/ad-banner.component.ts', 'class' ,'src/app/ad-banner.component.ts (excerpt)')(format='.')
:marked
- Components are added to the template by calling `createComponent` on the `ViewContainerRef` reference.
-
- `createComponent` returns a reference to the loaded component. The component reference can be used to pass input data or call methods to interact with the component.
+ The `loadComponent()` method is doing a lot of the heavy lifting here.
+ Take it step by step. First, it picks an ad.
- In the Ad banner, all components implement a common `AdComponent` interface to standardize the api for passing data to the components.
+.l-sub-section
+ :marked
+ **How _loadComponent()_ chooses an ad**
- Two sample components and the `AdComponent` interface are shown below:
+ The `loadComponent()` method chooses an ad using some math.
+
+ First, it sets the `currentAddIndex` by taking whatever it
+ currently is plus one, dividing that by the length of the `AdItem` array, and
+ using the _remainder_ as the new `currentAddIndex` value. Then, it uses that
+ value to select an `adItem` from the array.
+
+:marked
+ After `loadComponent()` selects an ad, it uses `ComponentFactoryResolver`
+ to resolve a `ComponentFactory` for each specific component.
+ The `ComponentFactory` then creates an instance of each component.
+
+ Next, you're targeting the `viewContainerRef` that
+ exists on this specific instance of the component. How do you know it's
+ this specific instance? Because it's referring to `adHost` and `adHost` is the
+ directive you set up earlier to tell Angular where to insert dynamic components.
+
+ As you may recall, `AdDirective` injects `ViewContainerRef` into its constructor.
+ This is how the directive accesses the element that you want to use to host the dynamic component.
+
+ To add the component to the template, you call `createComponent()` on `ViewContainerRef`.
+
+ The `createComponent()` method returns a reference to the loaded component.
+ Use that reference to interact with the component by assigning to its properties or calling its methods.
+
+a#selector-references
+:marked
+ #### Selector references
+
+ Generally, the Angular compiler generates a `ComponentFactory`
+ for any component referenced in a template. However, there are
+ no selector references in the templates for
+ dynamically loaded components since they load at runtime.
+
+ To ensure that the compiler still generates a factory,
+ add dynamically loaded components to the `NgModule`'s `entryComponents` array:
++makeExample('cb-dynamic-component-loader/ts/src/app/app.module.ts', 'entry-components' ,'src/app/app.module.ts (entry components)')(format='.')
+
+a#common-interface
+:marked
+ ### A common _AdComponent_ interface
+
+ In the ad banner, all components implement a common `AdComponent` interface to
+ standardize the API for passing data to the components.
+
+ Here are two sample components and the `AdComponent` interface for reference:
+makeTabs(
`cb-dynamic-component-loader/ts/src/app/hero-job-ad.component.ts,
@@ -113,9 +164,14 @@ include ../_util-fns
`hero-job-ad.component.ts,
hero-profile.component.ts,
ad.component.ts`
-)
+)
+a#final-ad-baner
:marked
+ ### Final ad banner
The final ad banner looks like this:
figure.image-display
- img(src="/resources/images/cookbooks/dynamic-component-loader/ads.gif" alt="Ads")
\ No newline at end of file
+ img(src="/resources/images/cookbooks/dynamic-component-loader/ads.gif" alt="Ads")
+
+:marked
+ See the .