Jednym z najpopularniejszych frameworków do tworzenia aplikacji typu single-page jest Angular. Jest on oparty o wzorzec MVC, co upraszcza tworzenie i testowanie takiej aplikacji. Wielu użytkowników generatora raportów FastReport potrzebuje wyświetlać swoje raporty w aplikacjach webowych Angular, co omówiliśmy w artykule Using FR Core Web Report in Single Page Application Angular 7. Teraz na stronie internetowej możemy wyświetlić nie tylko raport, ale również kostkę danych z FastCube .NET. Zobaczmy jak to zrobić.
Na początku powinieneś mieć zainstalowane: platformę Node.js oraz NET Core SDK 2.0, lub lepiej nowszy.
Możesz stworzyć aplikację używając szablonu z sdk. Aby to zrobić, wpisz polecenie w linii poleceń:
dotnet new angular -o FCubeAngular
Polecenie to tworzy aplikację demo gotową do uruchomienia. Jedyne, co musimy zrobić to dodać naszą funkcjonalność. Teraz w linii poleceń przechodzimy do katalogu z utworzoną aplikacją za pomocą komendy:
cd FCubeAngular
i zainstalować pakiety javascript za pomocą polecenia:
npm install
Przed przystąpieniem do pracy z naszą aplikacją webową należy przygotować pakiety Nuget z bibliotekami FastCube. Otwieramy rozwiązanie FastCube.Core.sln i konstruujemy obiekt. Otrzymamy dwa pakiety - FastCube.Web.2020.2.1.nupkg oraz FastCube.Core.2020.2.1.nupkg. Powinny być one umieszczone w lokalnym katalogu, który później wykorzystasz jako lokalne źródło pakietów Nuget.
Teraz możesz uruchomić projekt, który wcześniej utworzyłeś. Możemy od razu rozpocząć instalację pakietów FastCube. Otwórz menedżera pakietów Nuget. W prawym górnym rogu okna widoczna jest ikona koła zębatego, otwiera ona ustawienia źródeł pakietów. Kliknij na nią i dodaj nowe źródło pakietów - katalog z naszymi pakietami FastCube:
Wybierz dodane źródło pakietów z listy rozwijanej i zainstaluj pakiety:
Podłącz FastCube w pliku Startup.cs w Configure() poprzez dodanie kodu:
app.UseFastCube();
Nasza aplikacja zawiera już kontroler WeatherForecastController. Dodajmy do niego naszą metodę webową:
[HttpGet("[action]")] public IActionResult ShowCube() { Cube cube = new Cube(); Slice slice = new Slice() { Cube = cube }; FilterManager filterManager = new FilterManager() { Cube = cube }; WebGrid grid; grid = new WebSliceGrid() { Slice = slice }; ViewBag.WebGrid = grid; cube.SourceType = SourceType.File; cube.Load(Path.Combine("C:\\Users\\FR\\Downloads\\fastcube-net-master\\Demos\\Data\\", "Cubes", "calculated_measures.mdc")); return View(); }
Jeśli napotkasz problemy z wyświetlaniem zwracanego obrazu, sprawdź klasę, z której dziedziczy kontroler. Musi to być Controller, a nie BaseController.
Rozważmy teraz metodę sieciową, którą dodaliśmy. Obiekty Cube i Slice są połączone, ponieważ w rzeczywistości plaster jest częścią sześcianu. Do wyprowadzenia interaktywnej tabeli krzyżowej jest wykorzystany obiekt WebGrid. Może wyprowadzić zarówno plaster WebCubeGrid jak i kostkę WebSliceGrid. Pobieramy kostkę, którą wcześniej utworzyliśmy w desktopowej wersji FastCube .NET.
Aby wyświetlić, będziemy potrzebowali widoku. Można to zrobić klikając prawym przyciskiem myszy na ShowCube. Widok będzie zawierał pojedynczą linię kodu:
@await ViewBag.WebGrid.Render()
Przejdźmy do aplikacji SPA umieszczonej w katalogu ClientApp. Do katalogu app musimy dodać nasz komponent. Będzie on wyświetlał iframe z widokiem, który utworzyliśmy powyżej. W katalogu app dodajemy podkatalog cube. Dodajemy do niego dwa pliki: cube.component.html oraz cube.component.ts. Pierwszy z nich to display, drugi to kontroler.
Plik cube.component.html:
Mind the function safeUrl, która przekształca url do trybu bezpiecznego. Dodamy ją później.
Przycisk uruchamia funkcję Click, która instaluje flagę show do wyświetlenia ramki i ustawia url do metody ShowCube w kontrolerze na backendzie.
Jest to implementacja funkcji Click w pliku cube.component.ts:
import { Component } from '@angular/core'; @Component({ selector: 'app-cube-component', templateUrl: './cube.component.html' }) export class CubeComponent { public show: boolean = false; public url: string; Clicked() { this.show = true; this.url = "/WeatherForecast/ShowCube"; } }
Teraz dodajemy funkcję przekształcania linku w tryb normalny - dodajemy plik safeUrl.pipe.ts do tego samego katalogu:
import { Pipe, PipeTransform } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; @Pipe({ name: 'safeUrl' }) export class SafeUrlPipe implements PipeTransform { constructor(private sanitizer: DomSanitizer) { } transform(url) { return this.sanitizer.bypassSecurityTrustResourceUrl(url); } }
Dodany komponent i funkcja muszą być zarejestrowane w pliku app.module.ts:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; import { RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; import { NavMenuComponent } from './nav-menu/nav-menu.component'; import { HomeComponent } from './home/home.component'; import { CounterComponent } from './counter/counter.component'; import { FetchDataComponent } from './fetch-data/fetch-data.component'; import { CubeComponent } from './cube/cube.component'; import { SafeUrlPipe } from './cube/safeUrl.pipe'; @NgModule({ declarations: [ AppComponent, NavMenuComponent, HomeComponent, CounterComponent, FetchDataComponent, CubeComponent, SafeUrlPipe ], imports: [ BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }), HttpClientModule, FormsModule, RouterModule.forRoot([ { path: '', component: HomeComponent, pathMatch: 'full' }, { path: 'counter', component: CounterComponent }, { path: 'fetch-data', component: FetchDataComponent }, { path: 'cube', component: CubeComponent } ]) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Dodajemy również nowy nagłówek do menu w pliku nav-menu.component.html:
<header> <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3" > <div class="container"> <a class="navbar-brand" [routerLink]="['/']">FRCoreAngular</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-label="Toggle navigation" [attr.aria-expanded]="isExpanded" (click)="toggle()" > <span class="navbar-toggler-icon"></span> </button> <div class="navbar-collapse collapse d-sm-inline-flex justify-content-end" [ngClass]="{ show: isExpanded }" > <ul class="navbar-nav flex-grow"> <li class="nav-item" [routerLinkActive]="['link-active']" [routerLinkActiveOptions]="{ exact: true }"> <a class="nav-link text-dark" [routerLink]="['/']">Home</a> </li> <li class="nav-item" [routerLinkActive]="['link-active']"> <a class="nav-link text-dark" [routerLink]="['/counter']">Counter</a> </li> <li class="nav-item" [routerLinkActive]="['link-active']"> <a class="nav-link text-dark" [routerLink]="['/fetch-data']">Fetch data</a> </li> <li class="nav-item" [routerLinkActive]="['link-active']"> <a class="nav-link text-dark" [routerLink]="['/cube']">Cube</a> </li> </ul> </div> </div> </nav> </header>
Aplikacja jest gotowa. Uruchamiamy ją:
Ten prosty przykład pokazuje jak można wyświetlić kostkę danych opartą na bibliotekach FastCube w jednostronicowej aplikacji Angular. Teraz aplikacja webowa udostępnia Ci wygodne narzędzie do analizy danych. Możesz dodawać, usuwać lub filtrować dane.