CRUD 操作(建立、讀取、更新、刪除)是大多數 Web 應用程式的支柱。在本教程中,我們將向您展示如何建立前端使用 Angular、後端使用 GoAPI 的 CRUD 應用程序,從而形成完全整合且高效的全端解決方案。
先決條件
- Node.js
- 去1.21
- MySQL
設定 Angular 項目
安裝 Angular 18 並使用以下命令建立新專案。
npm install -g @angular/cli@18.0.0 ng new view --minimal --routing --style css --no-standalone --ssr=false
Angular 專案結構
└─ src ├─ app │ ├─ app-routing.module.ts │ ├─ app.component.ts │ ├─ app.interceptor.ts │ ├─ app.module.ts │ └─ components │ └─ product │ ├─ Create.component.ts │ ├─ Delete.component.ts │ ├─ Detail.component.ts │ ├─ Edit.component.ts │ ├─ Index.component.ts │ └─ Product.service.ts ├─ index.html ├─ main.ts └─ styles.css
*此項目結構將僅顯示我們計劃建立或修改的文件和資料夾。
角度專案文件
主要.ts
import { enableProdMode } from '@angular/core' import { platformBrowserDynamic } from '@angular/platform-browser-dynamic' import { AppModule } from './app/app.module' platformBrowserDynamic().bootstrapModule(AppModule).catch(e => console.error(e))
這個 main.ts 檔案透過使用 platformBrowserDynamic 函數引導 AppModule 來初始化 Angular 應用程式。它將應用程式設定為在瀏覽器中運行並處理引導過程中發生的任何錯誤。
應用程式模組.ts
import { NgModule } from '@angular/core' import { BrowserModule } from '@angular/platform-browser' import { FormsModule } from '@angular/forms' import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http' import { AppRoutingModule } from './app-routing.module' import { AppComponent } from './app.component' import { AppInterceptor } from './app.interceptor' import { ProductIndex } from './components/product/Index.component' import { ProductCreate } from './components/product/Create.component' import { ProductDetail } from './components/product/Detail.component' import { ProductEdit } from './components/product/Edit.component' import { ProductDelete } from './components/product/Delete.component' @NgModule({ declarations: [ AppComponent, ProductIndex, ProductCreate, ProductDetail, ProductEdit, ProductDelete, ], imports: [ BrowserModule, AppRoutingModule, FormsModule, HttpClientModule ], providers: [ { provide: HTTP_INTERCEPTORS, useClass: AppInterceptor, multi: true } ], bootstrap: [AppComponent] }) export class AppModule { }
AppModule 是 Angular 應用程式的主要模組。它導入核心 Angular 模組並使用 AppRoutingModule 設定路由。此模組聲明了各種與產品相關的組件。它還將 AppInterceptor 註冊為 HTTP 攔截器。 AppComponent 被設定為引導元件,使其成為應用程式的入口點。
應用程式組件.ts
import { Component } from '@angular/core' @Component({ selector: 'app-root', template: `<router-outlet></router-outlet>` }) export class AppComponent { }
app.component.ts 檔案定義了根元件 AppComponent,它使用
應用程式攔截器.ts
import { Injectable } from '@angular/core'; import { HttpInterceptor } from '@angular/common/http'; import { HttpRequest, HttpErrorResponse } from '@angular/common/http' import { Observable, throwError } from 'rxjs' import { HttpHandler } from '@angular/common/http' import { HttpEvent } from '@angular/common/http' @Injectable({ providedIn: 'root' }) export class AppInterceptor implements HttpInterceptor { baseURL = 'http://localhost:8080/api' intercept(request: HttpRequest<any>, next: HttpHandler): Observable<httpevent>> { return next.handle(request.clone({ url: this.baseURL + request.url, })) } } </httpevent></any>
AppInterceptor 類別是一個 Angular HTTP 攔截器,它在將所有傳出 HTTP 請求 URL 發送到伺服器之前將可配置的 baseURL 附加到它們。這允許應用程式集中並輕鬆管理基本 API 端點。
應用程式路由.module.ts
import { NgModule } from '@angular/core' import { RouterModule, Routes } from '@angular/router' import { ProductIndex } from './components/product/Index.component' import { ProductCreate } from './components/product/Create.component' import { ProductDetail } from './components/product/Detail.component' import { ProductEdit } from './components/product/Edit.component' import { ProductDelete } from './components/product/Delete.component' const routes: Routes = [ { path: '', redirectTo: 'product', pathMatch: 'full' }, { path: 'product', component: ProductIndex }, { path: 'product/create', component: ProductCreate }, { path: 'product/:id', component: ProductDetail }, { path: 'product/edit/:id', component: ProductEdit }, { path: 'product/delete/:id', component: ProductDelete } ] @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
AppRoutingModule 為 Angular 應用程式設定路由,包括用於列出、建立、檢視、編輯和刪除產品的產品相關路徑。它還包括一條從根路徑“/”重定向到產品列表頁面“/product”的路由。
創建.component.ts
import { Component } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { ProductService } from './Product.service' @Component({ selector: 'product-create', template: ` <div class="container"> <div class="row"> <div class="col"> <form ngnativevalidate method="post"> <div class="row"> <div class="mb-3 col-md-6 col-lg-4"> <label class="form-label" for="product_name">Name</label> <input id="product_name" name="name" class="form-control" maxlength="50"> <span class="text-danger">{{errors.name}}</span> </div> <div class="mb-3 col-md-6 col-lg-4"> <label class="form-label" for="product_price">Price</label> <input id="product_price" name="price" class="form-control" type="number"> <span class="text-danger">{{errors.price}}</span> </div> <div class="col-12"> <a class="btn btn-secondary" routerlink="/product">Cancel</a> <button class="btn btn-primary">Submit</button> </div> </div> </form> </div> </div> </div>` }) export class ProductCreate { product?: any = {} errors?: any = {} constructor(private router: Router, private route: ActivatedRoute, private ProductService: ProductService) { } create() { this.ProductService.create(this.product).subscribe(() => { this.router.navigateByUrl('/product') }, (e) => { alert(e.error) }) } }
ProductCreate 元件提供了一個用於建立新產品的表單,將名稱和價格的輸入欄位綁定到產品物件。提交後,它會呼叫 ProductService 建立產品並導航回產品清單。驗證錯誤會顯示在對應欄位旁邊,任何建立錯誤都會觸發警報。
刪除.component.ts
npm install -g @angular/cli@18.0.0 ng new view --minimal --routing --style css --no-standalone --ssr=false
Delete.component.ts 中的 ProductDelete 元件是一個處理產品刪除的 Angular 元件。它顯示一個帶有唯讀欄位的表單,其中顯示產品的詳細資訊(ID、名稱和價格)。當元件初始化時,它會使用路由中的產品 ID 來取得產品詳細資訊。提交表單時,delete() 方法呼叫 ProductService 刪除產品,然後重定向到產品清單。如果刪除過程中出現錯誤,則會顯示警報。
詳細資料.組件.ts
└─ src ├─ app │ ├─ app-routing.module.ts │ ├─ app.component.ts │ ├─ app.interceptor.ts │ ├─ app.module.ts │ └─ components │ └─ product │ ├─ Create.component.ts │ ├─ Delete.component.ts │ ├─ Detail.component.ts │ ├─ Edit.component.ts │ ├─ Index.component.ts │ └─ Product.service.ts ├─ index.html ├─ main.ts └─ styles.css
ProductDetail 元件顯示特定產品的詳細資訊。它根據路線中的 ID 檢索產品信息,並在唯讀欄位中顯示產品的 ID、名稱和價格。此元件提供“後退”和“編輯”按鈕用於導航。組件初始化時會取得並顯示產品詳細資訊。
編輯.component.ts
import { enableProdMode } from '@angular/core' import { platformBrowserDynamic } from '@angular/platform-browser-dynamic' import { AppModule } from './app/app.module' platformBrowserDynamic().bootstrapModule(AppModule).catch(e => console.error(e))
ProductEdit 元件允許使用者編輯現有產品。它使用路線中的產品 ID 檢索產品詳細信息,並將其顯示在帶有可編輯名稱和價格欄位的表單中。提交表單後,它會透過 ProductService 更新產品並導航回產品清單。取得或更新期間的任何錯誤都會顯示為警報,並且驗證錯誤會顯示在相關欄位旁邊。
索引.component.ts
import { NgModule } from '@angular/core' import { BrowserModule } from '@angular/platform-browser' import { FormsModule } from '@angular/forms' import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http' import { AppRoutingModule } from './app-routing.module' import { AppComponent } from './app.component' import { AppInterceptor } from './app.interceptor' import { ProductIndex } from './components/product/Index.component' import { ProductCreate } from './components/product/Create.component' import { ProductDetail } from './components/product/Detail.component' import { ProductEdit } from './components/product/Edit.component' import { ProductDelete } from './components/product/Delete.component' @NgModule({ declarations: [ AppComponent, ProductIndex, ProductCreate, ProductDetail, ProductEdit, ProductDelete, ], imports: [ BrowserModule, AppRoutingModule, FormsModule, HttpClientModule ], providers: [ { provide: HTTP_INTERCEPTORS, useClass: AppInterceptor, multi: true } ], bootstrap: [AppComponent] }) export class AppModule { }
ProductIndex 元件以表格格式顯示產品清單。它在初始化時從 ProductService 取得產品列表,並顯示每個產品的 ID、名稱和價格,以及用於檢視、編輯和刪除每個產品的操作按鈕。它還包括一個用於導航到產品創建頁面的按鈕。
產品.服務.ts
import { Component } from '@angular/core' @Component({ selector: 'app-root', template: `<router-outlet></router-outlet>` }) export class AppComponent { }
ProductService 使用 Angular 的 HttpClient 來執行產品管理的相關 HTTP 請求。它提供了以下方法:
- get(id?):透過 ID 取得產品詳細信息,如果沒有提供 ID,則取得產品清單。
- create(data?): 如果提供了數據,則建立一個新產品,否則取得建立產品頁面。
- edit(id, data?):如果提供了數據,則透過 ID 更新產品,否則取得產品詳細資訊進行編輯。
- delete(id, data?):如果提供了數據,則按ID刪除產品,否則獲取產品詳細資訊以進行確認。
樣式.css
import { Injectable } from '@angular/core'; import { HttpInterceptor } from '@angular/common/http'; import { HttpRequest, HttpErrorResponse } from '@angular/common/http' import { Observable, throwError } from 'rxjs' import { HttpHandler } from '@angular/common/http' import { HttpEvent } from '@angular/common/http' @Injectable({ providedIn: 'root' }) export class AppInterceptor implements HttpInterceptor { baseURL = 'http://localhost:8080/api' intercept(request: HttpRequest<any>, next: HttpHandler): Observable<httpevent>> { return next.handle(request.clone({ url: this.baseURL + request.url, })) } } </httpevent></any>
CSS 透過在容器上方新增空間並水平間隔按鈕來調整佈局。
索引.html
import { NgModule } from '@angular/core' import { RouterModule, Routes } from '@angular/router' import { ProductIndex } from './components/product/Index.component' import { ProductCreate } from './components/product/Create.component' import { ProductDetail } from './components/product/Detail.component' import { ProductEdit } from './components/product/Edit.component' import { ProductDelete } from './components/product/Delete.component' const routes: Routes = [ { path: '', redirectTo: 'product', pathMatch: 'full' }, { path: 'product', component: ProductIndex }, { path: 'product/create', component: ProductCreate }, { path: 'product/:id', component: ProductDetail }, { path: 'product/edit/:id', component: ProductEdit }, { path: 'product/delete/:id', component: ProductDelete } ] @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
HTML 作為 Angular 應用程式的主要入口點,包括用於樣式的 Bootstrap、用於圖示的 Font Awesome 和
設定 Go API 項目
npm install -g @angular/cli@18.0.0 ng new view --minimal --routing --style css --no-standalone --ssr=false
建立一個名為「example」的測試資料庫,並執行database.sql檔案導入表和資料。
Go API 專案結構
└─ src ├─ app │ ├─ app-routing.module.ts │ ├─ app.component.ts │ ├─ app.interceptor.ts │ ├─ app.module.ts │ └─ components │ └─ product │ ├─ Create.component.ts │ ├─ Delete.component.ts │ ├─ Detail.component.ts │ ├─ Edit.component.ts │ ├─ Index.component.ts │ └─ Product.service.ts ├─ index.html ├─ main.ts └─ styles.css
Go API 專案文件
.env
import { enableProdMode } from '@angular/core' import { platformBrowserDynamic } from '@angular/platform-browser-dynamic' import { AppModule } from './app/app.module' platformBrowserDynamic().bootstrapModule(AppModule).catch(e => console.error(e))
此文件保存連接資料庫的設定詳細資訊。
資料庫Go
import { NgModule } from '@angular/core' import { BrowserModule } from '@angular/platform-browser' import { FormsModule } from '@angular/forms' import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http' import { AppRoutingModule } from './app-routing.module' import { AppComponent } from './app.component' import { AppInterceptor } from './app.interceptor' import { ProductIndex } from './components/product/Index.component' import { ProductCreate } from './components/product/Create.component' import { ProductDetail } from './components/product/Detail.component' import { ProductEdit } from './components/product/Edit.component' import { ProductDelete } from './components/product/Delete.component' @NgModule({ declarations: [ AppComponent, ProductIndex, ProductCreate, ProductDetail, ProductEdit, ProductDelete, ], imports: [ BrowserModule, AppRoutingModule, FormsModule, HttpClientModule ], providers: [ { provide: HTTP_INTERCEPTORS, useClass: AppInterceptor, multi: true } ], bootstrap: [AppComponent] }) export class AppModule { }
這個 db.go 檔案配置與 GORM 的資料庫連線。 SetupDatabase函數載入環境變量,建構MySQL連接字串,並初始化GORM實例,該實例儲存在全域DB變數中。
路由器.go
import { Component } from '@angular/core' @Component({ selector: 'app-root', template: `<router-outlet></router-outlet>` }) export class AppComponent { }
此 router.go 檔案使用 Gin 框架為 Go 應用程式設定路由。 SetupRouter 函數使用 CORS 中間件初始化 Gin 路由器以允許所有來源。它定義了在 /api/products 路徑下處理產品相關操作的路由,每個路由都會對應到 ProductController 中的一個方法。最後,它啟動了 Gin 伺服器。
產品.go
import { Injectable } from '@angular/core'; import { HttpInterceptor } from '@angular/common/http'; import { HttpRequest, HttpErrorResponse } from '@angular/common/http' import { Observable, throwError } from 'rxjs' import { HttpHandler } from '@angular/common/http' import { HttpEvent } from '@angular/common/http' @Injectable({ providedIn: 'root' }) export class AppInterceptor implements HttpInterceptor { baseURL = 'http://localhost:8080/api' intercept(request: HttpRequest<any>, next: HttpHandler): Observable<httpevent>> { return next.handle(request.clone({ url: this.baseURL + request.url, })) } } </httpevent></any>
此product.go 檔案定義了與 GORM 一起使用的產品模型。它指定了一個具有三個欄位的 Product 結構體:Id(自動遞增主鍵)、Name、Price。
產品控制器.go
import { NgModule } from '@angular/core' import { RouterModule, Routes } from '@angular/router' import { ProductIndex } from './components/product/Index.component' import { ProductCreate } from './components/product/Create.component' import { ProductDetail } from './components/product/Detail.component' import { ProductEdit } from './components/product/Edit.component' import { ProductDelete } from './components/product/Delete.component' const routes: Routes = [ { path: '', redirectTo: 'product', pathMatch: 'full' }, { path: 'product', component: ProductIndex }, { path: 'product/create', component: ProductCreate }, { path: 'product/:id', component: ProductDetail }, { path: 'product/edit/:id', component: ProductEdit }, { path: 'product/delete/:id', component: ProductDelete } ] @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
product_controller.go 檔案定義了一個 ProductController 結構,其中包含使用 Gin 框架處理 Go 應用程式中產品的 CRUD 操作的方法。
- Index 檢索並傳回所有產品的清單。
- Get 透過 ID 取得並傳回單一產品。
- 建立 從請求主體建立新產品。
- 更新 使用請求正文中的資料更新現有產品。
- 刪除 按產品 ID 刪除產品。
主機程式
import { Component } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { ProductService } from './Product.service' @Component({ selector: 'product-create', template: ` <div class="container"> <div class="row"> <div class="col"> <form ngnativevalidate method="post"> <div class="row"> <div class="mb-3 col-md-6 col-lg-4"> <label class="form-label" for="product_name">Name</label> <input id="product_name" name="name" class="form-control" maxlength="50"> <span class="text-danger">{{errors.name}}</span> </div> <div class="mb-3 col-md-6 col-lg-4"> <label class="form-label" for="product_price">Price</label> <input id="product_price" name="price" class="form-control" type="number"> <span class="text-danger">{{errors.price}}</span> </div> <div class="col-12"> <a class="btn btn-secondary" routerlink="/product">Cancel</a> <button class="btn btn-primary">Submit</button> </div> </div> </form> </div> </div> </div>` }) export class ProductCreate { product?: any = {} errors?: any = {} constructor(private router: Router, private route: ActivatedRoute, private ProductService: ProductService) { } create() { this.ProductService.create(this.product).subscribe(() => { this.router.navigateByUrl('/product') }, (e) => { alert(e.error) }) } }
這個 main.go 檔案是 Go 應用程式的入口點。它導入配置和路由包,然後呼叫 config.SetupDatabase() 初始化資料庫連接,呼叫 router.SetupRouter() 設定應用程式的路由。
運行專案
運行 Angular 專案
import { Component } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { ProductService } from './Product.service' @Component({ selector: 'product-delete', template: ` <div class="container"> <div class="row"> <div class="col"> <form ngnativevalidate method="post"> <div class="row"> <div class="mb-3 col-md-6 col-lg-4"> <label class="form-label" for="product_id">Id</label> <input readonly id="product_id" name="id" class="form-control" value="{{product.Id}}" type="number" required> </div> <div class="mb-3 col-md-6 col-lg-4"> <label class="form-label" for="product_name">Name</label> <input readonly id="product_name" name="name" class="form-control" value="{{product.Name}}" maxlength="50"> </div> <div class="mb-3 col-md-6 col-lg-4"> <label class="form-label" for="product_price">Price</label> <input readonly id="product_price" name="price" class="form-control" value="{{product.Price}}" type="number"> </div> <div class="col-12"> <a class="btn btn-secondary" routerlink="/product">Cancel</a> <button class="btn btn-danger">Delete</button> </div> </div> </form> </div> </div> </div>` }) export class ProductDelete { product?: any = {} constructor(private router: Router, private route: ActivatedRoute, private ProductService: ProductService) { } ngOnInit() { this.get() } get() { return this.ProductService.delete(this.route.snapshot.params['id']).subscribe(data => { this.product = data }, e => { alert(e.error) }) } delete() { this.ProductService.delete(this.route.snapshot.params['id'], this.product).subscribe(() => { this.router.navigateByUrl('/product') }, (e) => { alert(e.error) }) } }
運行 Go API 專案
import { Component } from '@angular/core' import { ActivatedRoute } from '@angular/router' import { ProductService } from './Product.service' @Component({ selector: 'product-detail', template: ` <div class="container"> <div class="row"> <div class="col"> <form ngnativevalidate method="post"> <div class="row"> <div class="mb-3 col-md-6 col-lg-4"> <label class="form-label" for="product_id">Id</label> <input readonly id="product_id" name="id" class="form-control" value="{{product.Id}}" type="number" required> </div> <div class="mb-3 col-md-6 col-lg-4"> <label class="form-label" for="product_name">Name</label> <input readonly id="product_name" name="name" class="form-control" value="{{product.Name}}" maxlength="50"> </div> <div class="mb-3 col-md-6 col-lg-4"> <label class="form-label" for="product_price">Price</label> <input readonly id="product_price" name="price" class="form-control" value="{{product.Price}}" type="number"> </div> <div class="col-12"> <a class="btn btn-secondary" routerlink="/product">Back</a> <a class="btn btn-primary" routerlink="/product/edit/{{product.Id}}">Edit</a> </div> </div> </form> </div> </div> </div>` }) export class ProductDetail { product?: any = {} constructor(private route: ActivatedRoute, private ProductService: ProductService) { } ngOnInit() { this.get() } get() { return this.ProductService.get(this.route.snapshot.params['id']).subscribe(data => { this.product = data }, e => { alert(e.error) }) } }
開啟網頁瀏覽器並前往http://localhost:4200
你會發現這個產品清單頁面。
測試
點選「檢視」按鈕即可查看商品詳情頁面。
點擊「編輯」按鈕可以修改產品並更新其詳細資料。
點選「提交」按鈕儲存更新的產品詳細資料。
點擊「建立」按鈕以新增產品並輸入其詳細資料。
點選「提交」按鈕儲存新產品。
點選「刪除」按鈕即可刪除先前建立的產品。
點選「刪除」按鈕確認刪除該產品。
結論
總之,我們學習如何建立一個包含元件、視圖和路由的基本 Angular 項目,同時使用 Gin 框架作為後端設定 API。透過利用 GORM 進行資料庫操作,我們成功建立了一個動態前端,該前端與強大而高效的後端無縫整合。這種組合為開發現代全端 Web 應用程式奠定了堅實的基礎。
原始碼:https://github.com/stackpuz/Example-CRUD-Angular-18-Go
在幾分鐘內建立一個 Angular CRUD 應用程式:https://stackpuz.com
以上是使用 Go API 建立 Angular CRUD 應用程式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

goimpactsdevelopmentpositationality throughspeed,效率和模擬性。 1)速度:gocompilesquicklyandrunseff,IdealforlargeProjects.2)效率:效率:ITScomprehenSevestAndardArdardArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增強的Depleflovelmentimency.3)簡單性。

C 更適合需要直接控制硬件資源和高性能優化的場景,而Golang更適合需要快速開發和高並發處理的場景。 1.C 的優勢在於其接近硬件的特性和高度的優化能力,適合遊戲開發等高性能需求。 2.Golang的優勢在於其簡潔的語法和天然的並發支持,適合高並發服務開發。

Golang在实际应用中表现出色,以简洁、高效和并发性著称。1)通过Goroutines和Channels实现并发编程,2)利用接口和多态编写灵活代码,3)使用net/http包简化网络编程,4)构建高效并发爬虫,5)通过工具和最佳实践进行调试和优化。

Go語言的核心特性包括垃圾回收、靜態鏈接和並發支持。 1.Go語言的並發模型通過goroutine和channel實現高效並發編程。 2.接口和多態性通過實現接口方法,使得不同類型可以統一處理。 3.基本用法展示了函數定義和調用的高效性。 4.高級用法中,切片提供了動態調整大小的強大功能。 5.常見錯誤如競態條件可以通過gotest-race檢測並解決。 6.性能優化通過sync.Pool重用對象,減少垃圾回收壓力。

Go語言在構建高效且可擴展的系統中表現出色,其優勢包括:1.高性能:編譯成機器碼,運行速度快;2.並發編程:通過goroutines和channels簡化多任務處理;3.簡潔性:語法簡潔,降低學習和維護成本;4.跨平台:支持跨平台編譯,方便部署。

關於SQL查詢結果排序的疑惑學習SQL的過程中,常常會遇到一些令人困惑的問題。最近,筆者在閱讀《MICK-SQL基礎�...

golang ...


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能