Docs: Context - rollthecloudinc/quell GitHub Wiki
- Introduction
- Installation
- Overview
-
Key Concepts
- Context Plugins
- Inline Contexts
- Context Resolvers
-
Core Components
ContextModule
- Components (
ContextFormComponent
,ContextDatasourceComponent
, etc.)
-
Key Services
- ContextPluginManager
- InlineContextResolverService
- ResolvedContextPluginManager
-
Usage
- Define and Use Contexts
- Registering and Resolving Context Plugins
- API Reference
- Examples
- Testing
The Angular Context Library provides a structured approach to managing and resolving application contexts, allowing dynamic resolution, contextual data management, and plugin-based extensibility. Contexts can represent application states, runtime parameters, or forms of data that need to be resolved dynamically.
Install the library using npm:
npm install @your-org/context
Dependencies such as @rollthecloudinc/attributes
, @rollthecloudinc/plugin
, and @rollthecloudinc/datasource
might also be required as they provide support for plugins, attributes, and data sources.
The ContextModule
is at the core of this library and integrates its key concepts:
- Context Plugins: Define and register plugins to manage specific types of contexts.
- Dynamic Resolution: Resolve context data dynamically at runtime using resolvers.
- Inline Contexts: Inline definitions of contexts that can be resolved dynamically or stored for later use.
- Data Binding: Bind contexts to data sources, creating reusable content across the app.
The library extends the realm of dynamic data handling by providing tools for rendering, resolving, and managing contexts through plugins, components, and services.
A ContextPlugin
represents an entity used for resolving context-specific data. It is defined with:
- Name: Plugin identifier.
- Resolver: A class or service that resolves the plugin's data.
- Base Object: Parameters or base settings for the plugin.
Example:
export const routeContextFactory = (resolver: RouteResolver) => {
const baseObject = {
path: '',
};
return new ContextPlugin<string>({
id: 'route',
name: 'route',
title: 'Route',
global: true,
baseObject,
resolver,
});
};
An InlineContext
defines context configurations inline, including plugins and adaptors. Inline contexts can be used for dynamic resolution and runtime data management.
Adaptors supported:
-
Rest
: API integrations. -
Datasource
: Integration with data sources. -
Token
: Tokenized data inputs. -
Snippet
: Script or JSON snippets for dynamic configurations.
Example:
const inlineContext = new InlineContext({
name: 'user',
adaptor: 'rest',
rest: {
method: 'GET',
url: '/api/users',
},
});
Resolvers are services responsible for resolving the data associated with a context. A resolver implements the ContextResolver
interface, handling the process of transforming context plugins or inline contexts into resolved data.
The ContextModule
encapsulates all the components, services, and factories required for managing contexts. It integrates with Angular features such as forms, material design, and flex layout.
Key Features:
- Provides core services like
ContextPluginManager
andInlineContextResolverService
. - Dynamically registers resolvers, components, and plugins.
@NgModule({
imports: [
CommonModule,
ReactiveFormsModule,
MaterialModule,
TokenModule,
DatasourceModule,
],
providers: [
{ provide: CONTEXT_PLUGIN, useFactory: routeContextFactory, multi: true },
],
declarations: [
ContextFormComponent,
ContextDatasourceComponent,
DatasourceContextEditorComponent,
],
exports: [
ContextFormComponent,
ContextDatasourceComponent,
DatasourceContextEditorComponent,
],
})
export class ContextModule {}
- ContextFormComponent: A dynamic form for creating and managing contexts.
- ContextDatasourceComponent: Bridges data source-based contexts with forms.
- DatasourceContextEditorComponent: Provides an editing UI for context datasource configurations.
Example:
<classifieds-ui-context-form [context]="inlineContext"></classifieds-ui-context-form>
The ContextPluginManager
extends the BasePluginManager
class and manages the lifecycle of context plugins. It handles the registration and retrieval of plugins, enabling contexts to be loaded dynamically.
@Injectable({
providedIn: 'root',
})
export class ContextPluginManager extends BasePluginManager<ContextPlugin<string>, string> {
pluginDef() {
return of(new PluginDef({ name: 'context' }));
}
}
This service resolves inline contexts by invoking the appropriate plugin resolver or directly processing adaptors.
@Injectable({
providedIn: 'root',
})
export class InlineContextResolverService extends BaseInlineContextResolverService {
resolveMerged(contexts: Array<InlineContext>): Observable<any> {
return super.resolveMerged(contexts);
}
}
Manages plugins specific to resolved contexts by providing dynamic resolution logic.
@Injectable({
providedIn: 'root',
})
export class ResolvedContextPluginManager extends BasePluginManager<ResolvedContextPlugin<string>, string> {
register(plugin: ResolvedContextPlugin<string>) {
super.register(plugin);
}
}
Create a dynamic form using InlineContext
and the ContextFormComponent
.
Template:
<classifieds-ui-context-form [context]="inlineContext"></classifieds-ui-context-form>
Script:
const inlineContext = new InlineContext({
name: 'example',
adaptor: 'rest',
rest: {
method: 'GET',
url: '/api/data',
},
});
Define and register a new context plugin in the ContextModule
or via ContextPluginManager
.
contextPluginManager.register(
new ContextPlugin({
id: 'custom',
name: 'Custom Context',
resolver: new CustomResolver(),
})
);
-
ContextPlugin
: Represents a plugin for resolving contexts. -
InlineContext
: Inline configuration for context resolution. -
ContextDatasource
: Manages context's integration with data sources.
-
ContextPluginManager
: Manages the lifecycle of context plugins. -
InlineContextResolverService
: Resolves inline contexts dynamically. -
ParamContextExtractorService
: Extracts context references from parameter mappings.
-
ContextFormComponent
: A dynamic form builder for contexts. -
ContextDatasourceComponent
: Bridges contexts and data sources.
Use the ContextFormComponent
to define a REST-based inline context.
<classifieds-ui-context-form [context]="restContext"></classifieds-ui-context-form>
const restContext = new InlineContext({
name: 'rest-context',
adaptor: 'rest',
rest: {
method: 'GET',
url: '/api/example',
},
});
Register a custom context plugin at runtime.
contextPluginManager.register(
new ContextPlugin<string>({
id: 'custom-plugin',
name: 'Custom Plugin',
resolver: new CustomContextResolver(),
})
);
Unit testing can be performed using Angular's testing utilities.
To run tests, use:
npm run test
Example test configuration:
describe('ContextManagerService', () => {
let service: ContextManagerService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ContextManagerService);
});
it('should register and retrieve plugins', () => {
const plugin = new ContextPlugin({ id: 'test', name: 'Test Plugin' });
service.register(plugin);
expect(service.lookupContext('test')).toEqual(plugin);
});
});
The Angular Context Library provides an extensible framework for managing dynamic context data within Angular applications. Using its plugin system, resolvers, and inline configuration, it offers flexibility and modularity for managing contextual data at runtime.
For any enhancements or feature requests, feel free to reach out!