翻譯|使用教程|編輯:顏馨|2023-04-18 13:49:00.143|閱讀 220 次
概述:本章講述dhtmlxGantt在ASP.NET Core上的使用方法,歡迎查閱!
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
DHTMLX甘特圖是用于跨瀏覽器和超平臺應用程序的功能齊備的甘特圖。可滿足項目管理應用程序的大部分需求,具備完善的甘特圖表庫,功能強大,價格方便,提供豐厚而靈活的JavaScript API接口,與各種服務端技術(PHP,ASP.NET,Java等)簡單集合,滿足多種定制開發(fā)需求。
DHTMLX JavaScript UI 庫所開發(fā)的 JavaScript 組合易于使用和功能豐富,非常適合結合任何領導地位和任何復合性的解決方案,能力足足夠省創(chuàng)造和維保業(yè)務應用程序的時間,提供高生產力。
本教程將逐步指導您如何使用 ASP.NET Core 在服務端創(chuàng)建甘特圖。
啟動Visual Studio 2022并創(chuàng)建一個新的項目。選擇:創(chuàng)建一個新的項目。
接下來來選擇“ASP.NET Core Web App”并命名為DHX.Gantt。
自此,你已經創(chuàng)建了一個項目,可以繼續(xù)為甘特圖添加標記和腳本。
進入wwwroot并創(chuàng)建一個index.html文件。
在新創(chuàng)建的文件中,為甘特圖制作一個簡單的頁面。
請注意,甘特圖文件是在此演示中從 CDN 添加的。如果您有該組件的專業(yè)版本, 您需要手動將甘特圖文件添加到項目中。
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <link rel="stylesheet" type="text/css" /> <script src="http://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js"></script> <script> document.addEventListener("DOMContentLoaded", function(event) { // specifying the date format gantt.config.date_format = "%Y-%m-%d %H:%i"; // initializing gantt gantt.init("gantt_here"); // initiating data loading gantt.load("/api/data"); // initializing dataProcessor var dp = new gantt.dataProcessor("/api/"); // and attaching it to gantt dp.init(gantt); // setting the REST mode for dataProcessor dp.setTransactionMode("REST"); }); </script> </head> <body> <div id="gantt_here" style="width: 100%; height: 100vh;"></div> </body> </html>
當頁面被加載時,除了初始化甘特圖的數據加載外,還立即調用dataProcessor,所以用戶對甘特圖的所有修改都將被保存到后臺。后臺還沒有實現(xiàn),所以以后會更有意義。
接下來進入Program.cs,告訴應用程序使用index.html頁面。為了做到這一點,你需要將應用程序配置為從wwwroot文件夾中提供靜態(tài)文件。為此,你需要添加app.UseDefaultFiles()方法。你可以在這里找到更多細節(jié)。
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. // You may want to change this for production scenarios, // see //aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseDefaultFiles(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapRazorPages(); app.Run();
該方法允許提供默認文件。它將搜索wwwroot文件夾中的以下文件:app.UseDefaultFiles()
因此,你可以選擇其中的任何一個,而在本教程中使用的是 "index.html"。只是一個URL-rewriter,并不實際提供文件。為此,你還需要添加文件。UseDefaultFiles()UseStaticFiles()
一旦你完成了它,當你運行應用程序時,一個空的甘特圖就會出現(xiàn)在頁面上。注意,右上角的 "無效數據 "標簽顯示,因為因為仍然沒有合適的后臺來提供數據,所以被調用。當控制器實現(xiàn)后,gantt將能夠顯示任務和鏈接。gantt.load()
現(xiàn)在基本部分已經完成,是時候實現(xiàn)后端了。讓我們從實現(xiàn)模型類開始,之后再進行WebAPI控制器。
讓我們從數據模型開始。甘特的數據模型包括鏈接和任務,從.NET世界的角度來看,dhtmlxGantt對模型屬性使用非常規(guī)的名稱。有時客戶端的模型也包含一些客戶端或后端邏輯的屬性,但這些屬性不應該存儲在數據庫中。
為了處理這個問題,將使用數據傳輸對象(DTO)模式。兩種模型將被定義:
然后,這兩種模型之間的映射應該被實現(xiàn)。
模型
在項目文件夾中創(chuàng)建一個名為Models的新文件夾。這是實現(xiàn)模型類和 EF 上下文的位置。
任務模型
首先,為任務創(chuàng)建一個類。在Models文件夾中創(chuàng)建一個文件,命名為Task.cs。這可以通過調用Models文件夾的上下文菜單并選擇Add->Class來完成。
這個模型必須是這樣的:
namespace DHX.Gantt.Models { public class Task { public int Id { get; set; } public string? Text { get; set; } public DateTime StartDate { get; set; } public int Duration { get; set; } public decimal Progress { get; set; } public int? ParentId { get; set; } public string? Type { get; set; } } }
你可以查詢任務對象的所有屬性列表。
鏈接模型
再添加一個文件,為鏈接創(chuàng)建一個類:
namespace DHX.Gantt.Models { public class Link { public int Id { get; set; } public string? Type { get; set; } public int SourceTaskId { get; set; } public int TargetTaskId { get; set; } } }
模型已經準備好了,你可以開始配置數據庫連接。
為了配置數據庫連接,你需要采取下面列出的步驟:
安裝Entity Framework Core
Entity Framework Core將被用來管理應用程序與數據庫的通信。讓我們來安裝該框架:
或者使用軟件包管理器命令行:
PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer PM> Install-Package Microsoft.EntityFrameworkCore PM> Install-Package Microsoft.EntityFrameworkCore.Design
實體框架核心將用來管理應用程序與數據庫的通信。
創(chuàng)建實體上下文
接下來你需要定義一個與數據庫的會話,并啟用加載和保存數據。為此,創(chuàng)建Context:
using Microsoft.EntityFrameworkCore; namespace DHX.Gantt.Models { public class GanttContext : DbContext { public GanttContext(DbContextOptions<GanttContext> options) : base(options) { } public DbSet<Task> Tasks { get; set; } = null; public DbSet<Link> Links { get; set; } = null; } }
向數據庫添加第一批記錄
現(xiàn)在你可以向數據庫添加記錄了。讓我們創(chuàng)建數據庫初始化器,將任務填充到數據庫中。在Models文件夾中定義一個類,并將其稱為GanttSeeder。該類將有Seed()方法,將添加任務和鏈接到數據庫。
using Microsoft.EntityFrameworkCore; namespace DHX.Gantt.Models { public static class GanttSeeder { public static void Seed(GanttContext context) { if (context.Tasks.Any()) { return; // DB has been seeded } using (var transaction = context.Database.BeginTransaction()) { List<Task> tasks = new List<Task>() { new Task() { Id = 1, Text = "Project #2", StartDate = DateTime.Today.AddDays(-3), Duration = 18, Progress = 0.4m, ParentId = null }, new Task() { Id = 2, Text = "Task #1", StartDate = DateTime.Today.AddDays(-2), Duration = 8, Progress = 0.6m, ParentId = 1 }, new Task() { Id = 3, Text = "Task #2", StartDate = DateTime.Today.AddDays(-1), Duration = 8, Progress = 0.6m, ParentId = 1 } }; tasks.ForEach(s => context.Tasks.Add(s)); context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Tasks ON;"); context.SaveChanges(); context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Tasks OFF;"); List<Link> links = new List<Link>() { new Link() {Id = 1, SourceTaskId = 1, TargetTaskId = 2, Type = "1"}, new Link() {Id = 2, SourceTaskId = 2, TargetTaskId = 3, Type = "0"} }; links.ForEach(s => context.Links.Add(s)); context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Links ON;"); context.SaveChanges(); context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Links OFF;"); transaction.Commit(); } } } }
注冊數據庫
現(xiàn)在你應該在Program.cs中注冊數據庫。但首先你需要一個連接字符串。它將被存儲在應用程序設置的JSON文件中。創(chuàng)建appsettings.json文件(如果你已經有了,則打開它),并為數據庫添加一個連接字符串:
{ "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\\mssqllocaldb; Database=GanttDatabase;Trusted_Connection=True;" } }
數據庫上下文將通過依賴關系注入進行注冊。
將以下命名空間添加到 Program.cs:
using Microsoft.EntityFrameworkCore; using DHX.Gantt.Models;
該聲明將看起來像這樣:
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext<GanttContext>( options => options.UseSqlServer(connectionString));
要啟用控制器,需要調用services.AddControllers()方法:
builder.Services.AddControllers();
然后我們調用app.MapControllers()來注冊我們的控制器路線:
app.MapControllers();
下面是Program.cs的完整代碼:
using Microsoft.EntityFrameworkCore; using DHX.Gantt.Models; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext<GanttContext>( options => options.UseSqlServer(connectionString)); builder.Services.AddControllers(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. // You may want to change this for production scenarios, // see //aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseDefaultFiles(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapRazorPages(); app.MapControllers(); app.Run();
最后,你需要在應用啟動時初始化和播種數據庫。通常情況下,你會希望使用遷移來完成這個任務,但為了簡單起見,這里沒有使用遷移。
讓我們首先創(chuàng)建一個初始化的類。在Models文件夾中創(chuàng)建GanttInitializerExtension.cs文件:
namespace DHX.Gantt.Models { public static class GanttInitializerExtension { public static IHost InitializeDatabase(this IHost webHost) { var serviceScopeFactory = (IServiceScopeFactory?)webHost.Services.GetService(typeof(IServiceScopeFactory)); using (var scope = serviceScopeFactory!.CreateScope()) { var services = scope.ServiceProvider; var dbContext = services.GetRequiredService<GanttContext>(); dbContext.Database.EnsureDeleted(); dbContext.Database.EnsureCreated(); GanttSeeder.Seed(dbContext); } return webHost; } } }
接下來調用InitializeDatabase():
app.InitializeDatabase();
正如上面提到的,本教程中沒有使用遷移。而是使用簡單的EnsureCreated和種子。
當前部分已經完成,讓我們回到甘特圖。
定義DTOs和映射
現(xiàn)在是定義將用于Web API的DTO類的時候了。讓我們從任務的DTO類開始。在Models文件夾中創(chuàng)建一個文件并定義WebApiTask.cs類:
namespace DHX.Gantt.Models { public class WebApiTask { public int id { get; set; } public string? text { get; set; } public string? start_date { get; set; } public int duration { get; set; } public decimal progress { get; set; } public int? parent { get; set; } public string? type { get; set; } public bool open { get { return true; } set { } } public static explicit operator WebApiTask(Task task) { return new WebApiTask { id = task.Id, text = task.Text, start_date = task.StartDate.ToString("yyyy-MM-dd HH:mm"), duration = task.Duration, parent = task.ParentId, type = task.Type, progress = task.Progress }; } public static explicit operator Task(WebApiTask task) { return new Task { Id = task.id, Text = task.text, StartDate = task.start_date != null ? DateTime.Parse(task.start_date, System.Globalization.CultureInfo.InvariantCulture) : new DateTime(), Duration = task.duration, ParentId = task.parent, Type = task.type, Progress = task.progress }; } } }
而這是定義在Models文件夾中名為WebApiLink.cs的文件中的Link的DTO類:
namespace DHX.Gantt.Models { public class WebApiLink { public int id { get; set; } public string? type { get; set; } public int source { get; set; } public int target { get; set; } public static explicit operator WebApiLink(Link link) { return new WebApiLink { id = link.Id, type = link.Type, source = link.SourceTaskId, target = link.TargetTaskId }; } public static explicit operator Link(WebApiLink link) { return new Link { Id = link.id, Type = link.type, SourceTaskId = link.source, TargetTaskId = link.target }; } } }
當你完成這一步驟時,你應該得到以下的文件夾結構:
現(xiàn)在你可以運行該應用程序,以檢查一切是否到位。如果你沒有看到一個運行時錯誤,那么一切都很好。
現(xiàn)在是實際實現(xiàn)REST API的時候了。
添加控制器
創(chuàng)建控制器文件夾并創(chuàng)建三個空的API控制器:一個用于任務,另一個用于鏈接,還有一個用于整個數據集:
任務控制器
讓我們?yōu)槿蝿談?chuàng)建一個控制器。它將定義甘特任務的基本CRUD操作。
它是如何工作的:
在GET請求中,任務從數據庫加載,輸出是任務的數據傳輸對象;
在PUT/POST請求中,任務作為WebAPITask類來自客戶端。它們在dhtmlxGantt中以這種方式表示。因此,你應該把它們轉換為我們的EntityFramework數據模型的格式(任務類)。之后,就可以在DatabaseContext中保存更改。
using Microsoft.AspNetCore.Mvc; using DHX.Gantt.Models; namespace DHX.Gantt.Controllers { [Produces("application/json")] [Route("api/task")] public class TaskController : Controller { private readonly GanttContext _context; public TaskController(GanttContext context) { _context = context; } // GET api/task [HttpGet] public IEnumerable<WebApiTask> Get() { return _context.Tasks .ToList() .Select(t => (WebApiTask)t); } // GET api/task/5 [HttpGet("{id}")] public Models.Task? Get(int id) { return _context .Tasks .Find(id); } // POST api/task [HttpPost] public ObjectResult Post(WebApiTask apiTask) { var newTask = (Models.Task)apiTask; _context.Tasks.Add(newTask); _context.SaveChanges(); return Ok(new { tid = newTask.Id, action = "inserted" }); } // PUT api/task/5 [HttpPut("{id}")] public ObjectResult? Put(int id, WebApiTask apiTask) { var updatedTask = (Models.Task)apiTask; var dbTask = _context.Tasks.Find(id); if (dbTask == null) { return null; } dbTask.Text = updatedTask.Text; dbTask.StartDate = updatedTask.StartDate; dbTask.Duration = updatedTask.Duration; dbTask.ParentId = updatedTask.ParentId; dbTask.Progress = updatedTask.Progress; dbTask.Type = updatedTask.Type; _context.SaveChanges(); return Ok(new { action = "updated" }); } // DELETE api/task/5 [HttpDelete("{id}")] public ObjectResult DeleteTask(int id) { var task = _context.Tasks.Find(id); if (task != null) { _context.Tasks.Remove(task); _context.SaveChanges(); } return Ok(new { action = "deleted" }); } } }
鏈接控制器
接下來你應該為鏈接創(chuàng)建一個控制器:
using Microsoft.EntityFrameworkCore; using Microsoft.AspNetCore.Mvc; using DHX.Gantt.Models; namespace DHX.Gantt.Controllers { [Produces("application/json")] [Route("api/link")] public class LinkController : Controller { private readonly GanttContext _context; public LinkController(GanttContext context) { _context = context; } // GET api/Link [HttpGet] public IEnumerable<WebApiLink> Get() { return _context.Links .ToList() .Select(t => (WebApiLink)t); } // GET api/Link/5 [HttpGet("{id}")] public Link? Get(int id) { return _context .Links .Find(id); } // POST api/Link [HttpPost] public ObjectResult Post(WebApiLink apiLink) { var newLink = (Link)apiLink; _context.Links.Add(newLink); _context.SaveChanges(); return Ok(new { tid = newLink.Id, action = "inserted" }); } // PUT api/Link/5 [HttpPut("{id}")] public ObjectResult Put(int id, WebApiLink apiLink) { var updatedLink = (Link)apiLink; updatedLink.Id = id; _context.Entry(updatedLink).State = EntityState.Modified; _context.SaveChanges(); return Ok(new { action = "updated" }); } // DELETE api/Link/5 [HttpDelete("{id}")] public ObjectResult DeleteLink(int id) { var Link = _context.Links.Find(id); if (Link != null) { _context.Links.Remove(Link); _context.SaveChanges(); } return Ok(new { action = "deleted" }); } } }
數據控制器
最后,你需要為一個數據動作創(chuàng)建一個控制器:
using Microsoft.AspNetCore.Mvc; using DHX.Gantt.Models; namespace DHX.Gantt.Controllers { [Produces("application/json")] [Route("api/data")] public class DataController : Controller { private readonly GanttContext _context; public DataController(GanttContext context) { _context = context; } // GET api/data [HttpGet] public object Get() { return new { 數據 = _context.Tasks.ToList().Select(t => (WebApiTask)t), 鏈接 = _context.Links.ToList().Select(l => (WebApiLink)l) }; } } }
一切都準備好了。你可以運行該應用程序,看到成熟的甘特圖。
DHTMLX甘特圖享有超過十年的聲望,支持跨瀏覽器和跨平臺,性能比高,可滿足項目管理應用程序的所有需求,是最擅長的甘特圖表庫。
甘特圖控件交流群:764148812
歡迎加入群交流討論,獲得更多幫助請聯(lián)系
本站文章除注明轉載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn