Advanced custom attributes
Advanced patterns for building custom attributes in Aurelia 2, including template controllers, complex bindings, and performance optimization.
This guide covers advanced patterns for building custom attributes in Aurelia 2, focusing on template controllers, complex binding scenarios, and performance optimization techniques.
Template Controllers
Template controllers are custom attributes that control the rendering of their associated template. They're the mechanism behind built-in attributes like if, repeat, with, and switch.
Basic Template Controller Structure
All template controllers follow this pattern:
import { customAttribute, ICustomAttributeController, IViewFactory, IRenderLocation, ISyntheticView } from '@aurelia/runtime-html';
import { resolve } from '@aurelia/kernel';
@customAttribute({
name: 'my-controller',
isTemplateController: true,
bindables: ['value']
})
export class MyController {
public readonly $controller!: ICustomAttributeController<this>;
private readonly factory = resolve(IViewFactory);
private readonly location = resolve(IRenderLocation);
private view?: ISyntheticView;
public value: unknown;
public valueChanged(newValue: unknown): void {
this.updateView(newValue);
}
private updateView(show: boolean): void {
if (show && !this.view) {
this.view = this.factory.create().setLocation(this.location);
this.view.activate(this.view, this.$controller, this.$controller.scope);
} else if (!show && this.view) {
this.view.deactivate(this.view, this.$controller);
this.view = undefined;
}
}
public attaching(): void {
if (this.value) {
this.updateView(true);
}
}
public detaching(): void {
if (this.view) {
this.view.deactivate(this.view, this.$controller);
this.view = undefined;
}
}
}Usage:
Real-World Example: Visibility Controller
A practical template controller that shows/hides content based on user permissions:
Usage:
Advanced Template Controller: Loading States
A template controller that manages loading states with caching:
Usage:
Complex Two-Way Binding Attributes
Bi-directional Data Synchronization
Create attributes that can both read and write data:
Usage:
Multi-Value Binding
Handle multiple bindable properties with complex interactions:
Usage:
Performance Optimization Patterns
Lazy Initialization
Defer expensive operations until needed:
Batch Updates
Minimize DOM operations by batching updates:
Error Handling in Custom Attributes
Graceful Degradation
Handle errors gracefully without breaking the application:
Validation and Sanitization
Validate inputs before applying them:
Testing Custom Attributes
Unit Testing Template Controllers
Best Practices
1. Resource Management
Always clean up resources in detached():
2. Performance Considerations
Use
requestAnimationFramefor DOM updatesBatch operations when possible
Avoid frequent DOM queries
3. Error Handling
Validate inputs before applying changes
Provide fallback behaviors
Log errors for debugging
4. Type Safety
Use TypeScript interfaces for bindable properties
Implement proper type guards for runtime validation
These patterns provide a solid foundation for building robust, performant custom attributes that integrate well with Aurelia's architecture while handling edge cases gracefully.
Last updated
Was this helpful?