| {{f.name}} |
StartDate: {{value | date: 'dd/MM/yyyy'}}
``` PercentagePipe converts value to percentage: ``` value = 0.2; ...Percentage: {{value | percent}}
// 20% ``` Lowercase & Uppercase transform casing of a string: ```Lowercase text: {{value | lowercase}}
Uppercase text: {{value | uppercase}}
``` ### Creating a Custom Pipe We might need a specific transformation that is not built-in, then we can create a custom one. We must create a class which implements the PipeTransform class, and our logic must be placed in the transform method. ``` import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'capitalize' }) export class CapitalizePipe implements PipeTransform { public transform(text: string): string { return text[0].toUpperCase() + text.slice(1); } } ``` Then to use it, we must register it in our module declarations. 4 ## Component Communication [Chapter 1](#chapter-1) | [Chapter 2](#chapter-2) | [Chapter 3](#chapter-3) | [Chapter 4](#chapter-4) In Angular, components communicate with each other to share data such as object, string, number, array, or HTML. To understand component communication, first, we must understand the relationship between components. For example, when two components are not related to each other, they communicate through an Angular service. When you use a component inside another component, you create a component hierarchy. The Angular component being used inside another component is known as the child component and the enclosing component is known as the parent component. As shown in the image below, in context of AppComponent, app-child is a child component and AppComponent is a parent component. ``` import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: `Current count: @currentCount
@code { private int currentCount = 0; private void IncrementCount() { currentCount++; } } ``` The @page directive is used to specify the route for the component. The @code directive is used to specify the C# code for the component. The method IncrementCount will be invoked on the button click event. We can also use multiple, but distinct @page directives for a single component. We cannot set the same route for two different components. Doing so will result in a runtime error. ### Component base class We can create a base class for the component to separate the HTML and C# logic. The base class must derive from the ComponentBase class. We can use the @inherits directive to inherit a base class in a component. We have created a base class Welcome.razor.cs as shown below: ``` using Microsoft.AspNetCore.Components; namespace BlazorTutorial.Client.Pages; public class WelcomeBase : ComponentBase { public string WelcomeMessage { get; set; } = "Welcome to Blazor tutorial."; } ``` We have created a razor component Welcome.razor as shown below: ``` @page "/welcome" @inherits WelcomeBaseThe sum of number is : @(num1 + num2)
@code { [Parameter] public int num1 { get; set; } [Parameter] public int num2 { get; set; } } ``` The component parameters are annotated with the \[Parameter\] attribute. This component will accept two parameters of type integer and will display the sum of both numbers. Create another component Parent.razor as shown below: ``` @page "/parent"The sum of number is : @(num1 + num2)
@code { [Parameter] [EditorRequired] public int num1 { get; set; } [Parameter] [EditorRequired] public int num2 { get; set; } } ``` We must use the \[Parameter\] attribute while using the \[EditorRequired\] attribute. If we do not supply the required parameters while invoking the component, it will throw a compile-time warning. We can also provide default values to the component parameters. Look at the example shown below: ``` @page "/welcome"
The sum of number is : @(num1 + num2)
@code { [CascadingParameter(Name = "FirstNumber")] public int num1 { get; set; } [CascadingParameter(Name = "SecondNumber")] public int num2 { get; set; } } ``` Create a component Parent.razor as shown below: ``` @page "/parent"The product of number is : @(num1 * num2)
@code { [CascadingParameter(Name = "FirstNumber")] public int num1 { get; set; } [CascadingParameter(Name = "SecondNumber")] public int num2 { get; set; } } ``` Create a component Child.razor as shown below: ```The sum of number is : @(num1 + num2)
@SampleText
@code { string SampleText = "This is a sample text depicting one-way data-binding"; } ``` The C# field SampleText is bound to the HTML DOM using the @ symbol. ### Two-way data-binding It allows us to bind the value of a property or a field to HTML DOM elements, and vice versa. We can achieve two-way data binding by using the @bind attribute. We can bind a C# property on DOM events using the @bind:event="{EVENT}" attribute on the HTML elements, where {EVENT} is a placeholder for the DOM events. Look at the example shown below: ``` @page "/databinding"You name is: @Name
@code { string Name { get; set; } } ``` The value of the input field is bound to the Name property. The data binding will happen when the oninput event of the input field is triggered, i.e. when the value of the text box changes. NOTE: The attribute binding is case-sensitive. This means @bind, @bind:event is valid whereas, @Bind, @Bind:EVENT and other syntax using upper case characters are invalid. ### Bind multiple options using