Skyframe Documentation
Detail
Detail
What is a details component?
A details component is a component that fulfills the function of, as its name suggests, displaying the details of an entity. For those entities that has relations to other entities, it may contain list components (display mode) and nested details components.
What are the benefits?
- Loads the entity information automatically from the Skyframe backend API
- Loading state management
Creating a Skyframe details component
Entity definition
Say we have a Skyframe entity Customer with this definition below:
In our shared domain
@demo-project/shared/src/model/Customer.ts:
@Entity()export class Customer { @PrimaryKey() id: number;
@Field() email: string;
@Field() firstName: string;
@Field() lastName: string;}The angular entity
@demo-project/shared/src/model/Customer.ts:
export class Customer extends AngularEntity(SharedModels.Customer) {}You may want to learn how to create a Skyframe entity by reading the Domain Definition.
@demo-project/frontend/src/app/modules/customer/components/details/details.html:
<ng-template #details> <!-- Use [async pipe](https://angular.io/api/common/AsyncPipe) to evaluate the observable value of `entity` (fetched asynchronously from backend). --> <ng-container *ngIf="entity | async as entity"> <div class="d-flex flex-row"> <div class="card flex-auto flex-self-start"> <!-- The `entity` is an instance of `Customer` here. --> ID: {{ entity.id }} <br /> Email: {{ entity.email }} <br /> First name: {{ entity.firstName }} <br /> Last name: {{ entity.lastName }} <br /> </div> </div> </ng-container></ng-template>
<!-- Show details when data is ready --><ng-template [ngIf]="loading | async" [ngIfElse]="details"> Loading...</ng-template>Component class
@demo-project/frontend/src/app/modules/customer/components/details/details.ts:
import { Component } from '@angular/core';import { ActivatedRoute } from '@angular/router';
@Component({ selector: 'demo-project-customer-details', templateUrl: './form.html'})export class CustomerDetailsComponent extends DetailsComponent<Customer> { constructor(shell: Shell, activatedRoute: ActivatedRoute) { super(Customer, shell, activatedRoute); }}What we did here?
- We created our
CustomerDetailsComponentby extending theDetailsComponentclass, and passed a type parameterCustomerto it, meaning that we are creating a class that represents a Skyframe details component for theCustomerentity. - We added a constructor, which receives a two parameters:
shell: Shell: The orchestrator object of the Skyframe web app. It holds the context of the whole application, and it allows the form component to fetch data from the backend, know everything about a Skyframe entity, navigate to other pages, etc.activatedRoute: ActivatedRoute: Angular'sActivatedRouteprovider. Used for navigation and URL path lookup.
- We added a
super()call to the constructor and passed theCustomerclass as the first parameter. With this, we are making theshellknow what entity we are working with.
Using the details component
We have several ways to tell our details component which is the entity we want to retrieve:
By route parameter :id
If you use the details component inside a page whose route path has a route parameter :id, the details component will assume that the :id value is the entity's primary key:
// Route definition for the page that uses our `CustomerDetailsComponent`:const routes: Routes = [ ... { path: ':id', component: CustomerDetailsPageComponent }, ...];In the CustomerDetailsPageComponent template:
<h1>Customer details</h1><!-- Retrieves the customer with `:id` value as primary key --><demo-project-customer-details></demo-project-customer-details>Passing a entity instance through [entity] input
<h1>Customer details</h1><!-- Shows the details with the `customer`'s values. No HTTP requests will be made. --><demo-project-customer-details [entity]="customer"></demo-project-customer-details>Angular lifecycle hooks
These are the Angular lifecycle hooks used by DetailsComponent:
ngOnInit: Component state initialization entity data retrieval.ngOnDestroy: For disposing subscriptions and destroying the component state.
If you are overriding one of these methods, please make sure that you are calling the parent method, otherwise, the DetailsComponent would not work as expected.
import { OnDestroy, OnInit } from '@angular/core';
export class MyDetailsComponent extends DetailsComponent<MyEntity> implements OnInit, OnDestroy { public ngOnInit(): void { super.ngOnInit();
/* Do something else... */ }
public ngOnDestroy(): void { super.ngOnDestroy();
/* Do something else... */ }}