Building a Custom Element Wrapper in Angular
This challenge focuses on integrating custom elements (web components) into an Angular application. Custom elements offer a way to reuse components across different frameworks, and Angular provides mechanisms to effectively manage and interact with them. Your task is to create an Angular component that wraps a pre-existing custom element, providing Angular-specific functionality like data binding and event handling.
Problem Description
You are tasked with building an Angular component, my-custom-element-wrapper, that encapsulates a custom element named my-custom-element. my-custom-element is assumed to be already defined and registered in the browser (you don't need to define it; it's provided). This wrapper component should:
- Instantiate and Attach: Create an instance of
my-custom-elementwithin the Angular component's lifecycle. - Property Binding: Allow Angular properties to be bound to attributes of the custom element. Specifically, the Angular component should have a property called
namewhich should be reflected as thenameattribute on the custom element. - Event Handling: Listen for a custom event named
custom-eventemitted bymy-custom-element. When this event is fired, the Angular component should log a message to the console containing the event's detail property. - Lifecycle Management: Ensure the custom element is properly destroyed when the Angular component is destroyed to prevent memory leaks.
Expected Behavior:
- When the Angular component is initialized, an instance of
my-custom-elementshould be created and appended to the component's host element. - Changes to the
nameproperty in the Angular component should be reflected in thenameattribute of the custom element. - When
my-custom-elementemits thecustom-event, the Angular component should log a message to the console. - When the Angular component is destroyed, the custom element instance should be removed.
Examples
Example 1:
Input: Angular component with name="John Doe"
Output: A `my-custom-element` instance with the attribute `name="John Doe"` is created and attached to the Angular component's host element. When `my-custom-element` emits `custom-event` with detail `{message: "Hello from custom element!"}`, the console logs "Event received: Hello from custom element!".
Explanation: The Angular component binds the `name` property to the custom element's `name` attribute and listens for the `custom-event`.
Example 2:
Input: Angular component with name="Jane Smith" and the custom element emits `custom-event` with detail `{message: "Goodbye!"}`.
Output: The `my-custom-element` instance's `name` attribute is updated to "Jane Smith". The console logs "Event received: Goodbye!".
Explanation: The Angular component updates the attribute and handles the event.
Example 3: (Component Destruction)
Input: The Angular component is destroyed.
Output: The `my-custom-element` instance is removed from the DOM and its resources are released.
Explanation: Proper lifecycle management prevents memory leaks.
Constraints
- The custom element
my-custom-elementis already defined and registered. You do not need to define it. Assume it has anameattribute and emits acustom-eventwith adetailproperty. - The Angular component should be a standard Angular component, using TypeScript.
- The solution should be compatible with a recent version of Angular (e.g., Angular 14+).
- The solution should avoid using
anytype where possible.
Notes
- Consider using Angular's lifecycle hooks (e.g.,
ngOnInit,ngOnDestroy) to manage the custom element's lifecycle. - You'll need to use the
ElementAPI to interact with the custom element. - Think about how to handle potential errors when creating or interacting with the custom element.
- This problem focuses on the integration aspect; you don't need to implement the custom element itself. Focus on how Angular can effectively wrap and manage it.
- You can use a simple
divas the host element for the Angular component.