@servlyadmin/runtime-angular
v0.1.39
Published
Angular wrapper for Servly runtime components
Maintainers
Readme
@servlyadmin/runtime-angular
Angular wrapper for Servly runtime renderer. Render Servly components in your Angular applications with full slot support, state management, and reactive updates.
Installation
npm install @servlyadmin/runtime-angular
# or
yarn add @servlyadmin/runtime-angular
# or
pnpm add @servlyadmin/runtime-angularRequirements
- Angular 14.0.0 or higher
- @servlyadmin/runtime-core (installed automatically)
Setup
Import the ServlyModule in your Angular module:
import { NgModule } from '@angular/core';
import { ServlyModule } from '@servlyadmin/runtime-angular';
@NgModule({
imports: [
ServlyModule,
// ... other imports
],
})
export class AppModule {}Or for standalone components:
import { Component } from '@angular/core';
import { ServlyComponent, ServlySlotDirective } from '@servlyadmin/runtime-angular';
@Component({
standalone: true,
imports: [ServlyComponent, ServlySlotDirective],
// ...
})
export class MyComponent {}Quick Start
import { Component } from '@angular/core';
@Component({
selector: 'app-example',
template: `
<servly-component
id="my-component"
[props]="{ title: 'Hello World' }"
(load)="onLoad($event)"
(error)="onError($event)"
></servly-component>
`,
})
export class ExampleComponent {
onLoad(data: any) {
console.log('Component loaded:', data);
}
onError(error: Error) {
console.error('Failed to load:', error);
}
}API Reference
ServlyComponent Inputs
| Input | Type | Default | Description |
|-------|------|---------|-------------|
| id | string | required | Component ID from the registry |
| version | string | 'latest' | Version specifier |
| props | object | {} | Props to pass to the component |
| state | object | undefined | Additional state for bindings |
| context | object | undefined | Additional context for bindings |
| eventHandlers | object | undefined | Event handlers keyed by element ID |
| cacheStrategy | 'memory' \| 'localStorage' \| 'none' | 'memory' | Caching strategy |
| retryConfig | object | undefined | Retry configuration |
| forceRefresh | boolean | false | Force refresh from registry |
| showSkeleton | boolean | true | Show loading skeleton |
| enableStateManager | boolean | false | Enable state management |
| initialState | object | undefined | Initial state |
Outputs
| Output | Type | Description |
|--------|------|-------------|
| load | EventEmitter<ComponentData> | Emitted on successful load |
| error | EventEmitter<Error> | Emitted on load failure |
| slotsReady | EventEmitter<Record<string, HTMLElement>> | Emitted when slots are ready |
| stateChange | EventEmitter<StateChangeEvent> | Emitted on state change |
| ready | EventEmitter<void> | Emitted when fully rendered |
Slot Directive
Use the servlySlot directive to define slot content:
<servly-component id="my-component">
<ng-template servlySlot="header">
<h1>Custom Header</h1>
</ng-template>
<ng-template servlySlot="footer">
<p>Custom Footer</p>
</ng-template>
</servly-component>Custom Loading/Error States
<servly-component id="my-component">
<!-- Custom loading state -->
<div servlyFallback>
<mat-spinner></mat-spinner>
<p>Loading component...</p>
</div>
<!-- Custom error state -->
<div servlyError>
<mat-icon>error</mat-icon>
<p>Failed to load component</p>
</div>
</servly-component>Advanced Usage
With State Management
import { Component } from '@angular/core';
import { StateChangeEvent } from '@servlyadmin/runtime-angular';
@Component({
selector: 'app-counter',
template: `
<servly-component
id="counter-component"
[props]="{ count: count }"
[enableStateManager]="true"
[initialState]="{ count: 0 }"
(stateChange)="onStateChange($event)"
></servly-component>
`,
})
export class CounterComponent {
count = 0;
onStateChange(event: StateChangeEvent) {
if (event.key === 'count') {
this.count = event.value;
}
}
}Using ServlyStateService
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ServlyStateService } from '@servlyadmin/runtime-angular';
@Component({
selector: 'app-stateful',
template: `...`,
})
export class StatefulComponent implements OnInit, OnDestroy {
private unsubscribe?: () => void;
constructor(private servlyState: ServlyStateService) {}
ngOnInit() {
// Initialize state
this.servlyState.initialize({ user: null });
// Subscribe to changes
this.unsubscribe = this.servlyState.subscribe((event) => {
console.log('State changed:', event);
});
}
ngOnDestroy() {
this.unsubscribe?.();
}
updateUser(user: any) {
this.servlyState.set('user', user);
}
getUser() {
return this.servlyState.get('user');
}
}With Event Handlers
import { Component } from '@angular/core';
@Component({
selector: 'app-form',
template: `
<servly-component
id="form-component"
[eventHandlers]="handlers"
></servly-component>
`,
})
export class FormComponent {
handlers = {
'submit-btn': {
onClick: (event: Event) => {
console.log('Submit clicked!');
this.handleSubmit();
},
},
'email-input': {
onChange: (event: Event) => {
const input = event.target as HTMLInputElement;
console.log('Email:', input.value);
},
},
};
handleSubmit() {
// Handle form submission
}
}Accessing Component Methods
import { Component, ViewChild } from '@angular/core';
import { ServlyComponent } from '@servlyadmin/runtime-angular';
@Component({
selector: 'app-example',
template: `
<servly-component #servly id="my-component"></servly-component>
<button (click)="reload()">Reload</button>
`,
})
export class ExampleComponent {
@ViewChild('servly') servlyComponent!: ServlyComponent;
reload() {
// Access component methods
this.servlyComponent.retry();
}
getSlotElement(name: string) {
return this.servlyComponent.getSlotElement(name);
}
getSlotNames() {
return this.servlyComponent.getSlotNames();
}
}Version Specifiers
<!-- Exact version -->
<servly-component id="my-component" version="1.2.3"></servly-component>
<!-- Caret range -->
<servly-component id="my-component" version="^1.0.0"></servly-component>
<!-- Tilde range -->
<servly-component id="my-component" version="~1.2.0"></servly-component>
<!-- Latest -->
<servly-component id="my-component" version="latest"></servly-component>Reactive Props
import { Component } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Component({
selector: 'app-reactive',
template: `
<servly-component
id="my-component"
[props]="props$ | async"
></servly-component>
`,
})
export class ReactiveComponent {
props$ = new BehaviorSubject({ count: 0 });
increment() {
const current = this.props$.value;
this.props$.next({ count: current.count + 1 });
}
}TypeScript Support
Full TypeScript support is included:
import type {
ComponentData,
BindingContext,
StateChangeEvent,
CacheStrategy,
RetryConfig,
} from '@servlyadmin/runtime-angular';Re-exported Utilities
import {
// Fetching
fetchComponent,
prefetchComponents,
setRegistryUrl,
// Caching
invalidateCache,
clearAllCaches,
// Version utilities
parseVersion,
compareVersions,
// State management
StateManager,
getValueByPath,
// Event system
EventSystem,
getEventSystem,
} from '@servlyadmin/runtime-angular';License
MIT
