I have a bunch of static pages that use various components that are placed wherever a HTML designer likes. e.g. within any page on a WordPress site.
Though the sample components shown here are simple Panels, but in reality there are all sorts of components, e.g. Search, Lists, Editors, Views etc...
Currently they have been done on lots of Wordpress Sites where each and every page can have totally different layouts. In the past we used Angular 1.5 where the WP developer you could just put our app tag up near the body and then any widget (we have about 30) could be placed 1 or more times in any page.
Components can be re-used so making the components root components via the bootstrap[] property does not make sense as you can only use a root component once on a page. As seen in my second example.
Technique 1
Here is a screenshot and Plunker for the first setup. Notice that I have 4 area's in which I place 3 components with component 1 being reused.
This Example is done by laying out the components inside a single root component, which is impractical for my use case where Wordpress Pages will have totally different layout and composition requirements. .
Plunkr
Technique 2
I have tried using a technique where each widget is bootstrapped as a root component, based on this post Bootstrapping Multiple Applications Sprinkling Angular 2 components inside a non-angular page.
But when I use this technique the 2nd instance of a widget does not load. AKA widget 1.
Plunkr
See example with bootstrapping
Technique 2 - Has further problems
If you have bootstrapped 3 root components, you MUST use all of them otherwise Angular throws up an error about the root component that you did not use.
Plunker
Technique 3
The use of <ng-content></ng-content>
does not seem to work root components.
See: Angular2 Root Component with ng-content
For this kind of widgets the better is to have an ng2 application instantiated per each widget like Bootstrap multiples applications. I did post a possible solution there.
I do implement an ApplicationFactory which create a dynamic selector like:
moduleFactory(selector: string, childModule : ModuleWithProviders) {
@Component({
selector, // dynamic selector
...
})
export class AppComponent implements AfterViewInit{
constructor(resolver: ComponentFactoryResolver){}
ngAfterViewInit() {
// Cretate a Child components dynamic
// mapping from childModule::[bootstrap] components decoration
}
}
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule
],
bootstrap: [AppComponent]
})
class AppModule { }
platformBrowserDynamic()
.bootstrapModule(AppModule, {providers: childModule.providers});
}
In then in ngAfterViewInit you may create a dynamic component using a ComponentFactoryResolver
This is not an ideal solutions but it works
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With