I would like to use Angular routing in a component that's bootstrapped as a custom element. It appears that if I place several custom elements on a page, only the last element receives the router-outlet.
Here is the repo with a sample on GitHub
I generated this sample project by:
Do you know why only the last instance of my component has router-output and all other instances route to that element?
Each route in this array is a JavaScript object that contains two properties. The first property, path , defines the URL path for the route. The second property, component , defines the component Angular should use for the corresponding path.
In order to use it in another Angular app, we don't really need to build the component; as it is a simple Angular component, we can just import and use it. But if we only have access to compiled files, we can include them with the scripts field in our angular.
In Angular, the best practice is to load and configure the router in a separate, top-level module. The router is dedicated to routing and imported by the root AppModule . By convention, the module class name is AppRoutingModule and it belongs in the app-routing.module.ts in the src/app directory.
It's because you can have only one primary router outlet per module. (Primary outlet is the one with no name specified in the template) I found this article helpful: https://www.techiediaries.com/angular-router-multiple-outlets/
You can work around that by naming your outlets - but since you are using the same app components I think you will need something along those lines:
app.component.ts:
@Input() name: string;
getRouterLink(url: string): object {
return { outlets: { primary: url, first: url, second: url } };
}
index.html
<my-el name="first"></my-el>
<my-el name="second"></my-el>
app-routing.module.ts:
const routes: Routes = [
{ path: "", redirectTo: "page1", pathMatch: "full" },
{ path: "page1", component: Page1Component },
{ path: "page2", component: Page1Component },
{ outlet: "first", path: "page1", component: Page1Component },
{ outlet: "first", path: "page2", component: Page2Component },
{ outlet: "second", path: "page1", component: Page1Component },
{ outlet: "second", path: "page2", component: Page2Component }
];
app.component.html:
<h2><a href="#" [routerLink]="getRouterLink('page1')">Page1</a></h2>
<h2><a href="#" [routerLink]="getRouterLink('page2')">Page2</a></h2>
<ng-container *ngIf="name === 'first'">
<router-outlet name="first"></router-outlet>
</ng-container>
<ng-container *ngIf="name === 'second'">
<router-outlet name="second"></router-outlet>
</ng-container>
This could be made nicer ofc but should be enough to illustrate the point.
I've tried binding router-outlet's 'name' dynamically (<router-outlet [name]="name">
) so it's not wrapped in those ng-containers, but that's not possible since 'name' is an @Attribute and not an @Input of the router-outlet (https://github.com/angular/angular/blob/f8096d499324cf0961f092944bbaedd05364eea1/packages/router/src/directives/router_outlet.ts#L50)
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