Skyframe Documentation

Entity modules

Entity modules

What is a Module?

A module is a container for a group of entities, pages, components, and providers (services), dedicated to a specific application domain. The Skyframe modules rely on Angular's feature modules, please head to the official Angular feature module guide to learn more.

What is a Page?

In terms of Angular, a Page is actually a regular component. But in the context of Skyframe, a Page is a component that contains the entire view of a use case (see Use cases ), such as a dashboard, a login page, or a popup for entity creation/modification. It may contain a header and a footer, and nested components with business logic. Ideally, a Page should only have presentation logic, and the business logic must be delegated to services or its nested components.

A Page example:

<h1>Article Details</h1>
<!-- app-article-details is a component with business logic -->
<app-article-details></app-article-details>
<button (click)="deleteArticle()" class="btn btn-sm btn-danger mt-2">
Delete
</button>
<button (click)="editArticle()" class="btn btn-sm btn-outline-secondary mt-2">
Edit
</button>

What is a Component?

A Skyframe Component is also a regular Angular component. It may have some basic business logic and brings more functionalities than a Page. A Component is typically a CRUD Component (see CRUD Components).

There are three main types of Components provided by Skyframe:

What is a Service?

A Service is a Provider class that can be injected (see Introduction to services and dependency injection) by Pages and Components. While Pages and Components focus on presenting data to the view, we use Services to share tasks or data among them. They must be UI-independent, and only provide features and functions related to business logic.

How can I declare an entity module?

Create an Angular module

First, we create an Angular NgModule:

@NgModule({
imports: [
CommonModule,
CoreModule,
RouterModule,
ReactiveFormsModule,
FormsModule,
SharedModule,
ListModule,
SkyframeModule,
...
],
declarations: [
ArticleAddPageComponent,
ArticleAddPopupComponent,
ArticleDetailsComponent,
ArticleDetailsPageComponent,
ArticleEditPageComponent,
ArticleEditPopupComponent,
ArticleFormComponent,
ArticleListComponent,
ArticleFilterComponent,
ArticleListPageComponent
],
entryComponents: [
ArticleAddPopupComponent,
ArticleEditPopupComponent
],
exports: [
ArticleAddPageComponent,
ArticleAddPopupComponent,
ArticleDetailsComponent,
ArticleFormComponent,
ArticleListComponent,
ArticleFilterComponent
]
})
export class ArticleModule {}

Create an Angular routing module

Define the routes to page components in a separated routing module (see Angular Router guide):

const routes: Routes = [
{ path: '', component: ArticleListPageComponent },
{ path: 'add', component: ArticleAddPageComponent },
{ path: ':id', component: ArticleDetailsPageComponent },
{ path: ':id/edit', component: ArticleEditPageComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes), ArticleModule],
exports: [RouterModule]
})
export class ArticleRoutingModule {}

Create a Skyframe Angular entity

import { SharedModels } from '@my-project/shared';
import { AngularEntity } from '@skyframe/angular';
export class Article extends AngularEntity(SharedModels.Article) {}

Import the entity into the module

@NgModule({
imports: [...],
declarations: [...],
entryComponents: [...],
exports: [...]
})
@SkfModule({
entities: [Article]
})
export class ArticleModule {}

Register use cases

We should register the use cases for pages and popups. See Use cases for further explanations.

@NgModule({
imports: [...],
declarations: [...],
entryComponents: [...],
exports: [...]
})
@SkfModule({
entities: [Article]
})
export class ArticleModule {
constructor(private shell: Shell) {
this.shell.registerUseCase(Article, 'list', '/article', ArticleListComponent);
this.shell.registerUseCase(Article, 'add', '/article/add', ArticleFormComponent);
this.shell.registerUseCase(Article, 'add:popup', '/article/add', ArticleAddPopupComponent);
this.shell.registerUseCase(Article, 'edit:popup', '/article/add', ArticleEditPopupComponent);
this.shell.registerUseCase(Article, 'detail', '/article/:id', ArticleDetailsComponent);
this.shell.registerUseCase(Article, 'edit', '/article/:id/edit', ArticleDetailsComponent);
}
}