Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

188
Vistas
Choose between 2 Angular components on the module

I have an Angular project used by some clients. So, every time I build the project I do it for one client, changing a property on a configuration file. Also, I may have slightly different logic on some components for different clients. For instance:

@Component({
  selector: 'my-component',
  templateUrl: './component.template.html',
  styleUrl: './component.styles.scss'
})
export class MyBaseComponent {
  getName() {
    return 'Base';
  }

  /* Other logic here ... */
}

@Component({
  selector: 'my-component',
  templateUrl: './component.template.html',
  styleUrl: './component.styles.scss'
})
export class MyClientComponent extends MyBaseComponent {
  getName() {
    return 'Client';
  }
} 

@Component({
  selector: 'my-component',
  templateUrl: './component.template.html',
  styleUrl: './component.other-client.styles.scss'
})
export class MyOtherClientComponent extends MyBaseComponent {
  getName() {
    return 'Other Client';
  }
} 

Now, what I would like is for this to be totally transparent for other modules that import this components. Note that all three selectors are named the same. I tried to implement the module like this:

import { client } from '../environment';
import { MyBaseComponent, MyClientComponent, MyOtherClientComponent } from './components';

function chooseComponent() {
  switch(client) {
    case 'my-client':
      return MyClientComponent;
    case 'my-other-client':
      return MyOtherClientComponent;
    default:
      return MyBaseComponent;
  }
}

@NgModule({
  declarations: [chooseComponent()],
  imports: [],
  providers: [],
  exports: [chooseComponent()],
})
export class TestComponentModule {}

But Angular does not let me do this. Do you guys know what's the correct way to implement this. Sure, I could use and if to change the logic. But that's ugly.

Also, if I would like to change a piece of the html template, based on the client. What would be the best to do it? Imagine, if client is X I show a button, and if its Y I show label. Is using ngIf the only way?

Thanks!

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

There are several ways to do this. 1- you could create a container component and use ngSwitch in the template. In this case you would need to use a unique selector for each component and use it in the container component template: e.g.

Container Template

<ng-container [ngSwitch]="client">
  <my-client-component *ngSwitchCase="'my-client'"></my-client-component>
  <my-other-client-component *ngSwitchCase="'my-other-client'"></my-other-client-component>
</ng-container>

2- You could use dynamic rendering and do the magic in your container component typescript file. You could define a method with switch on client variable and let angular render the component in the view based on the client. For more details about how to render a dynamic component see the angular dynamic component render documentation. In case you do not want to load the other client component to the browser, you could put your components in a lazy module and import them with dynamic import. See this nice article https://medium.com/@ckyidr9/lazy-load-feature-modules-without-routing-in-angular-9-ivy-220851cc7751

over 4 years ago · Santiago Trujillo Denunciar

0

If am not wrong, you can do this in quite a few ways:

  1. Using RouteGuard and lazyloading: That would look like this:
// Have each component in 3 different modules. Have 3 route guards and use them to load the exact module. Something like this: 

import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivate } from '@angular/router';
import { client } from '../environment';

@Injectable()
export class MyClientGuard implements CanActivate {
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): boolean {
    return client === 'my-client';
  }
}

@Injectable()
export class MyOtherClientGuard implements CanActivate {
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): boolean {
    return client === 'my-other-client';
  }
}

@Injectable()
export class MyBaseComponentGuard implements CanActivate {
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): boolean {
    return (client !== 'my-client' || client !== 'my-other-client');
  }
}

const routes: Routes = [
  {
    path: 'base-component',
    loadChildren: () => import('./base-component/base-component.module').then(m => m.BaseComponentModule),
    canActivate: [MyBaseComponentGuard]
  },
  {
    path: 'other-client',
    loadChildren: () => import('./other-client/other-client.module').then(m => m.OtherClientModule),
    canActivate: [MyOtherClientGuard]
  },
  {
    path: 'my-client',
    loadChildren: () => import('./my-client/my-client.module').then(m => m.MyClientModule),
    canActivate: [MyClientGuard]
  }
];
  1. Second way of doing this is: Using Resolvers. You may refer to this documentation for more details on resolvers: https://angular.io/api/router/Resolve Have not used this much but might help you.

  2. Third way is having everything in a single module and single component and based on environment.client value, using ngIf / ngtemplate to show the correct templates in the page.

  3. One more way is use the same component and define some @Input() clientValue: string input value like that and based on that you can show hide values using ng-container and ng-template.

over 4 years ago · Santiago Trujillo Denunciar

0

Not directly related but you could have a look at this app I built some time ago https://stackblitz.com/edit/angular-rxjs-in-memory-caching-dynamic?file=src%2Fapp%2Froot.component.ts

This simulates a dashboard with widgets where data for the widget is retrieved from the server, the API simulates random delays on each call and caches the API calls in the browser.

In terms of configuration, you can see how you can define what widgets you want to see on the page, it uses the dynamics component loader to load the components. This was built in Angular 8, there are more elegant ways to do this with Ivy from Angular 9

enter image description here

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda