Creating components – Components and Pages-2
With this command, the Angular CLI will create a folder with the following four files in addition to updating the diary module with the new component.
- entry-item.component.css: This file will contain the component’s style sheet. Angular manages to solve a big pain point of a web application, which is the CSS scope of each component. With this feature, we can specify the component’s styling without having to worry about whether it will affect an application’s CSS even using the same property or selector name.
- entry-item.component.html: This file contains the component’s HTML template and, although the extension seems to indicate that we can only use HTML tags, in the template file, we can use Angular directives, as we will study in this chapter.
- entry-item.component.spec.ts: This file contains the unit test for the component, which we will detail in Chapter 10, Design for Tests: Best Practices.
- entry-item.component.ts: This is the TypeScript file that represents the component itself. All other files are optional, making it possible for you to create a component with just this file, although this is not a practice widely applied in Angular projects and is only recommended for very small components.
In the entry-item.component.ts file, the Angular CLI created the following structure:
import { Component } from ‘@angular/core’;
@Component({
selector: ‘app-entry-item’,
templateUrl: ‘./entry-item.component.html’,
styleUrls: [‘./entry-item.component.css’]
})
export class EntryItemComponent {
}
With this example, we reinforce the definition that a component is a TypeScript class, and by using the @Component decorator, we indicate to Angular where the parts to assemble it are.
The main properties are as follows:
- selector: This is an optional property that defines what the component’s selector will be if it is used in the template of another component. Components that represent a page do not need to have a selector defined as they are instantiated from a route. The Angular CLI suggests the selector based on your application’s prefix defined in the prefix property of the angular.json file, along with the name you defined in the ng g command.
- templateUrl: This defines the path of the HTML file that contains the component’s template. Alternatively, we can use the template property to define a string with all the component’s HTML.
- styleUrls: This defines the path of the CSS files that contain the component’s styling. A detail of this property is that it is an array, so it is possible to have more than one CSS file linked to the component. Alternatively, we can use the style property to define a string containing the component’s CSS.
In the entry-item.component.html file, we will place the snippet that represents an item in a list of exercises in our gym diary:
<div class=”mb-4 border-b bg-white p-4″>
<span class=”font-bold”>Date:</span> 2023-03-20<br />
<span class=”font-bold”>Exercise:</span> Bench press<br />
<span class=”font-bold”>Sets:</span> 3<br />
<span class=”font-bold”>Reps:</span> 10
</div>
Here, we have the representation of an item, with the difference being that we are using the <div> element instead of <li> because we want our component to be as reusable as possible here – it may not necessarily be used within a list and within an <ul> element.
Let’s put our component to use. In the diary.component component, let’s refactor the diary.component.html file as follows:
<div class=”min-h-screen bg-gray-200″>
<header class=”bg-blue-500 py-4 text-white”>
<div class=”mx-auto max-w-6xl px-4″>
<h1 class=”text-2xl font-bold”>Workout diary</h1>
</div>
</header>
<main class=”mx-auto mt-8 max-w-6xl px-4″>
<section class=”mb-8″>
<h2 class=”mb-4 text-xl font-bold”>List of entries</h2>
<ul class=”rounded border shadow”>
<li>
<app-entry-item />
</li>
<li>
<app-entry-item />
</li>
<!– more entries here –>
</ul>
</section>
<button
class=”rounded bg-blue-500 py-2 px-4 font-bold text-white hover:bg-blue-700″
>
Add new entry
</button>
</main>
</div>
Using the app-entry-item selector, we are consuming our new component on the page. From version 15 of Angular, we can use self-closing tags for components, so we have used <app-entry-item /> here, but if you prefer the previous way, <app-entry-item> </app-entry- item> also still works.
Running our project, we can see that it continues to work. However, the data is the same in both items. We now need a way to pass information between components, and we’ll see how to do that in the next section.