Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Preston Lamb
Preston Lamb

Posted on • Originally published atMedium on

     

Conditional Templates for Angular Components

tldr;

One of the many benefits of working in Nx workspaces is the ability to share code between applications. In an Angular application, that means being able to share components between multiple applications. The problem is that different applications may have different design systems, even though the functionality is the same. I recently ran into this issue, and wasn't sure the best route to go. In my situation, our old design system was based on (highly customized) Bootstrap. Our new app uses Tailwind. So I was a little stuck on what to do next. I first thought that I could just throw the Tailwind classes in the HTML mixed in with the Bootstrap classes. This would technically work, because if the app doesn't include Bootstrap styles, then it would only take the Tailwind styles and vice versa. But my worry was that the HTML templates would get out of control with extremely long class lists. But I realized there had to be a way to conditionally swap out the HTML for a template. That's what I decided to try and do, using theenvironment.ts file.

Component Outline

For this example, let's create a demo card component we can use. We'll make two HTML templates, one with some Bootstrap card styles and one with some Tailwind card styles.

Bootstrap:

<!-- card-bootstrap.component.html --><divclass="card"style="width: 18rem;"><img[src]="imageUrl"class="card-img-top"alt="..."><divclass="card-body"><h5class="card-title">{{ cardTitle }}</h5><pclass="card-text">{{ cardDescription }}</p><a[routerLink]="url"class="btn btn-primary">Go somewhere</a></div></div>
Enter fullscreen modeExit fullscreen mode

Tailwind:

<!-- card-tailwind.component.html --><divclass="p-20 bg-purple-100"><divclass="bg-white rounded-lg shadow-lg w-full md:w-1/2"><imgclass="rounded-t-lg"[src]="imageUrl"alt="..."><divclass="p-6"><h2class="font-bold mb-2 text-2xl text-purple-800">{{ cardTitle }}</h2><pclass="text-purple-700 mb-2">{{ cardDescription }}</p><aclass="text-purple-600 underline text-sm hover:text-purple-500"[routerLink]="url">Go somewhere</a></div></div></div>
Enter fullscreen modeExit fullscreen mode

Now that we have the two templates, let's look at the component's TypeScript file.

// card.component.ts@Component({selector:'app-card',templateUrl:'',styleUrls:['card.component.scss']})exportclassCardComponent{@Input()cardTitle:string;@Input()cardDescription:string;@Input()url:string;@Input()imageUrl:string;// other component logic}
Enter fullscreen modeExit fullscreen mode

Now in this example, I intentionally left thetemplateUrl in the decorator blank. Normally, it would have the valuecard.component.html. But our component has two templates that we made above. Next up we'll figure out one way to change between the two template files.

Conditionally Changing the Template File

Depending on how long you've been using Angular, you may or may not be familiar with theenvironment.ts file. This file is used at build time for your Angular application. You can read a little bit more about the difference between build time and runtime configuration in Angular appsin this article. In short, the values in the environment.ts file can be used throughout the application, but if any values change the app needs to be built again for the changes to take place. When an Angular app is generated by the CLI, there is anenvironment.ts file that is used for local development by default, and anenvironment.prod.ts file which is used when the app is built for production environments. When the files are used is determined in theangular.json file.

Now that we have briefly covered what theenvironment.ts file is and how to use it, we'll talk about using it for our scenario. I figured I could use thisenvironment file to determine which template the app should use when building the app. If I added a value to the file, such asuseTailwindTemplate, I could use that to determine which template to use. Let's look at the component's TypeScript file again.

// card.component.tsimport{environment}from'src/environments/environment';@Component({selector:'app-card',templateUrl:environment.useTailwindTemplate?'card-tailwind.component.html':'card-bootstrap.component.html',styleUrls:['card.component.scss']})
Enter fullscreen modeExit fullscreen mode

Now the value oftemplateUrl, is set based off the value of the attribute in theenvironment file. To test it out, you can build the application with theenvironment.useTailwindTemplate attribute set totrue and open the app in your browser. You should see the Tailwind card on the page. If you set the value tofalse, you should see the Bootstrap card on the page.

Conclusion

The example here is simple, and potentially excessive for a simple card component. But imagine your component has some complicated logic that you don't want to repeat in multiple components. Any time you have multiple components with the same logic that needs to be repeated, the two components get out of sync quickly. In those cases, this may be a good option. In our case, we will be using this option to use Tailwind in one app and Bootstrap in another. Also, it will allow us to incrementally convert the Bootstrap app to Tailwind. The logic can remain in a single TypeScript file, while being able to use multiple templates.

This is just one way you could conditionally swap out the template file for a component. For some other ideas, you cancheck out this Twitter thread.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Preston Lamb is a full stack JavaScript developer, Angular GDE, ngChampion writer for the ng-conf blog, & co-organizer of the Angular Community Meetup.
  • Location
    Roy, UT
  • Education
    BS in Computer Science from Utah State University
  • Work
    Software Developer at MotivHealth
  • Joined

More fromPreston Lamb

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp