Widgets
The main idea behind a widget is to create an easy to use API for dynamically loading any content and adding it to the application in any form and at any place.
Widgets are Angular modules that should be added to the application by lazy loading.
Check out examples to learn more.
Widget is simply an Angluar module that has been annotated with OpWidget() annotation.
Thanks to this annotation NgOP can easily lazy load such module for you and use it in your components.
Widgets can be loaded only through lazy loading.
It serves as the basic type of content for NgOP.
NgOP takes care of how widgets are being loaded. It provides a simple API and also some additional features to make your application more consistent and your code more reusabel.
Widget can contain any type of content. They can also be easily presented in different ways. For example, each widget can be used as a simple component , or as a modal, or notification or any other type of content. At the same time each being lazy loaded and fully reusable.
Start points
Start point is simply an Angular component that will be used as main component when widget will be used.
Each widget needs to have defined at least one start point.
Defining a widget
To define module as NgOP widget you need to import OpWidget and annotate module with it.
Assuming that we have a module called TestModule and a main component called TestComponent, annotating module would look liek this:
@OpWidget({
default: TestComponent,
})
@NgModule({
declarations: [
TestComponent,
],
})
export class TestModule {}
Naming our starting point default will tell NgOP to use this start point each time user will not explicitly giva name of any other one.
Multiple starting points
You can also declare more than one starting point per widget.
Let's assume that we have a component called OtherTestComponent.
We could define it as an additional start point as follows:
@OpWidget({
default: TestComponent,
other: OtherTestComponent,
})
@NgModule({
declarations: [
TestComponent,
OtherTestComponent,
],
})
export class TestModule {}
We gave OtherTestComponent staring point a simple name other.
To access it you would have to provide this name to configuration object of op-widget component.
We will go into details on how to do it below.
Widget component <op-widget/>
To start using widgets you need to import OpWidgetModule.
This module contains op-widget component that is a container for a NgOP widgets.
To work properly op-widget needs to know which widget you want to load and present, therefore it requires some configuration data.
This configuration is represented by interface OpWidgetConfig.
interface OpWidgetConfig {
module: Promise<any> | (() => Promise<any>);
component?: string;
data?: { [k: string]: any };
loader?: string;
}
Simple usage
Taking TestModule as our example widget we could use it by simply defining following configuration
@Component({
template: `<op-widget [config]="config"></op-widget>`
})
class SomeComponent {
config: OpWidgetConfig = {
module: import('path-to-test-module'),
},
}
This will simply load TestModule widget and instantiate TestComponent as it is defined as widget's default start point.
Explicit starting point
To load load widget and instantiate other starting points you will have to use component property and assing starting point's name to it.
@Component({
template: `<op-widget [config]="config"></op-widget>`
})
class SomeComponent {
config: OpWidgetConfig = {
module: import('path-to-test-module'),
component: 'other',
},
}
Providing data
One other thing you can do is to provide some custom data to instantiated widget's starting point.
To do this you need to use property data and set needed data.
Let's assume our OtherTestComponent will look like this:
@Component({
template: `Your text: {{ text }}`,
})
export class OtherTestComponent {
@Input() text!: string;
}
You can see that this component declares text as input data. We can provide our text to our widget as follows:
@Component({
template: `<op-widget [config]="config"></op-widget>`
})
class SomeComponent {
config: OpWidgetConfig = {
module: import('path-to-test-module'),
component: 'other',
data: {
text: 'This is my text',
},
},
}
You do not need to define @Input() to you properties.
NgOP simply assigns all given data to the instance of the component even when they are not defined as angular inputs.
We consider it a good practice to use @Input() annotation to make clear which data comes from outside of component.
Using a loading component
Loading component is a component that will be presented until your widget will instantiate.
By the default NgOP will use default loading component, declared in OpCoreModule.
You can also tell op-widget to use placeholder other than the default one (if available).
To do that you can use configuration's placeholder property and give it your preferred placeholder's name.
Assuming we have defined a loading component with nametest in OpCoreModule, we can use it as follows:
@Component({
template: `<op-widget [config]="config"></op-widget>`
})
class SomeComponent {
config: OpWidgetConfig = {
module: import('path-to-test-module'),
placeholder: 'test',
},
}
NgOP will instantiate it immediatly with op-widget and show it as a placeholder until TestModule and its default starting point will be instantiated and used.