Одним из самых популярных фреймворков для создания одностраничных приложений является Angular. Он основан на шаблоне MVC, что упрощает разработку и тестирование такого приложения. Многим пользователям генератора отчетов FastReport необходимо отображать свои отчеты в веб-приложениях Angular и мы это уже рассмотрели в статье использование FR Core Web Report в Single Page Application Angular 7. Теперь появилась возможность отображать на веб-странице не только отчет, но и куб данных из FastCube .NET. Давайте рассмотрим как это сделать.
В самом начале у вас должны быть установлены: платформа Node.js и NET Core SDK 2.0, но лучше “посвежее”.
Вы можете создать приложение используя шаблон из sdk. Для этого в командной строке вводим команду:
dotnet new angular -o FCubeAngular
Эта команда создаст готовое к запуску демонстрационное приложение. Да так, что нам лишь останется дополнить его своим функционалом. Теперь в командной строке переходим в каталог с созданным приложением с помощью команды:
cd FCubeAngular
и устанавливаем javascript пакеты с помощью команды:
npm install
Перед началом работы с нашим веб-приложением, предварительно нужно подготовить Nuget пакеты с библиотеками FastCube. Откройте решение FastCube.Core.sln и выполните построение. В результате вы получите два пакета - FastCube.Web.2020.2.1.nupkg и FastCube.Core.2020.2.1.nupkg. Их нужно поместить в какую-либо локальную папку, которую будем использовать в дальнейшем в качестве локального источника пакетов Nuget.
Теперь можно запустить созданный нами ранее проект. И сразу же приступим к установке пакетов FastCube. Открываем менеджер пакетов Nuget. В правом верхнем углу окна вы увидите значок шестеренки - он открывает настройки источников пакетов. Нажимаем на него и добавляем новый источник пакетов - папку с нашими пакетами FastCube:
Выбираем добавленный источник пакетов в выпадающем списке и устанавливаем пакеты:
Подключаем FastCube в файле Startup.cs в методе Configure() добавим код:
app.UseFastCube();
Наше приложение уже содержит контроллер WeatherForecastController. Давайте добавим в него свой веб-метод:
[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(); }
Если у вас возникли проблемы с возвращаемым представлением, то обратите внимание на класс, от которого наследуется контроллер. Должен быть Controller, а не BaseController.
Теперь рассмотрим добавленный нами веб-метод. Объекты Cube и Slice связаны, так как, по сути, срез является частью куба. Для вывода интерактивной перекрестной таблицы используется объект WebGrid. Он может выводить, как срез WebCubeGrid, так и куб WebSliceGrid. Загружаем куб, который ранее создали в десктоп версии FastCube .NET.
Для его отображения нам потребуется представление. Это можно сделать с помощью правого клика по сигнатуре метода ShowCube. Представление будет содержать единственную строку кода:
@await ViewBag.WebGrid.Render()
Перейдем к SPA приложению, которое размещается в папке ClientApp. Нам нужно добавить свой компонент в папку app. Он будет отображать iframe с представлением, которое мы создали выше. Добавляем в папку app подпапку cube. В нее добавим два файла cube.component.html и cube.component.ts. Первый - это отображение, второй - контроллер.
Файл cube.component.html:
Обратите внимание на функцию safeUrl, которая преобразует url к безопасному виду. Мы добавим её чуть позже.
Кнопка активирует функцию Click, которая установит флаг show для отображения фрейма, а также задаст url к методу ShowCube в контроллере на бекенде.
Собственно вот и реализация функции Click в файле 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"; } }
А теперь добавим функцию преобразования ссылки к нормализованному виду - файл safeUrl.pipe.ts добавим в ту же папку:
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); } }
Добавленный компонент и функцию нужно зарегистрировать в файле 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 { }
А также добавим новый пункт в меню в файле 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>
Приложение готово. Запустим его:
В этом простом примере мы рассмотрели, как в одностраничном приложении Angular отобразить куб данных на основе библиотек FastCube. Теперь в веб-приложении вам доступен удобный инструмент для анализа данных. Вы можете добавлять и убирать измерения, факты, а также фильтровать свои данные.