Implementing a Custom ngSwitch Directive in Angular
This challenge asks you to implement a simplified version of Angular's ngSwitch directive. ngSwitch allows you to conditionally render different templates based on the value of an expression. Building this directive will solidify your understanding of Angular directives, template parsing, and conditional rendering.
Problem Description
You need to create an Angular directive called CustomNgSwitch that mimics the core functionality of Angular's ngSwitch. The directive should:
- Accept an input property called
ngSwitch: This property will hold the expression whose value will be used for switching. - Accept multiple input properties named
ngSwitchCase: EachngSwitchCaseproperty will hold a value. The corresponding template for angSwitchCasewill be rendered if thengSwitchexpression matches thengSwitchCasevalue. - Accept a default template: If none of the
ngSwitchCasevalues match thengSwitchexpression, a default template should be rendered. This default template is identified byngSwitchDefault. - Render the appropriate template: Based on the value of the
ngSwitchexpression, the directive should render the template associated with the matchingngSwitchCaseor thengSwitchDefaulttemplate if no match is found.
Key Requirements:
- The directive must be a structural directive (using
*ngSwitch). - The directive must dynamically create and render the appropriate template based on the input values.
- The directive should handle cases where no
ngSwitchCasematches thengSwitchexpression.
Expected Behavior:
When the ngSwitch expression changes, the directive should re-evaluate the ngSwitchCase values and render the corresponding template. If no ngSwitchCase matches, the ngSwitchDefault template should be rendered.
Edge Cases to Consider:
ngSwitchexpression isnullorundefined.- No
ngSwitchCasedirectives are present. - Multiple
ngSwitchCasedirectives have the same value. (The first one encountered should take precedence). ngSwitchDefaultis not present.
Examples
Example 1:
Input:
Template:
<div *customNgSwitch="expression">
<div *ngSwitchCase="1">Case 1</div>
<div *ngSwitchCase="2">Case 2</div>
<div *ngSwitchDefault>Default</div>
</div>
expression = 2
Output:
<div>
<div>Case 2</div>
</div>
Explanation: The expression is 2, which matches the value of ngSwitchCase="2". Therefore, the template associated with that case is rendered.
Example 2:
Input:
Template:
<div *customNgSwitch="expression">
<div *ngSwitchCase="'A'">Case A</div>
<div *ngSwitchCase="'B'">Case B</div>
<div *ngSwitchDefault>Default</div>
</div>
expression = 'C'
Output:
<div>
<div>Default</div>
</div>
Explanation: The expression is 'C', which does not match either 'A' or 'B'. Therefore, the default template is rendered.
Example 3: (Edge Case)
Input:
Template:
<div *customNgSwitch="expression">
<div *ngSwitchCase="1">Case 1</div>
<div *ngSwitchCase="1">Case 1 Duplicate</div>
<div *ngSwitchDefault>Default</div>
</div>
expression = 1
Output:
<div>
<div>Case 1</div>
</div>
Explanation: Although there are two ngSwitchCase directives with the value 1, only the first one is considered.
Constraints
- The directive must be implemented in TypeScript.
- The directive should be compatible with Angular version 14 or higher.
- The directive should not rely on external libraries.
- The directive should be performant enough to handle a reasonable number of
ngSwitchCasedirectives (e.g., up to 10). Avoid unnecessary DOM manipulations. - The
ngSwitchexpression can be any primitive type (string, number, boolean).
Notes
- Consider using
TemplateRefandViewContainerRefto dynamically create and render templates. - Think about how to efficiently store and compare the
ngSwitchCasevalues. - Pay close attention to the structural directive syntax (
*customNgSwitch). - Remember that Angular's change detection will automatically trigger re-evaluation when the
ngSwitchexpression changes. - Focus on the core functionality of
ngSwitch. Advanced features likengSwitchWhenare not required for this challenge.