Go API を使用した Angular CRUD アプリの構築

Patricia Arquette
リリース: 2024-11-04 21:36:02
オリジナル
423 人が閲覧しました

Building an Angular CRUD App with a Go API

CRUD 操作 (作成、読み取り、更新、削除) は、ほとんどの Web アプリケーションのバックボーンです。このチュートリアルでは、フロントエンドに Angular、バックエンドに GoAPI を使用して CRUD アプリを構築し、完全に統合された効率的なフルスタック ソリューションを実現する方法を示します。

前提条件

  • Node.js
  • Go 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
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

*このプロジェクト構造には、作成または変更する予定のファイルとフォルダーのみが表示されます。

Angular プロジェクト ファイル

main.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 アプリケーションを初期化します。ブラウザーで実行されるようにアプリケーションを設定し、ブートストラップ プロセス中に発生するエラーを処理します。

app.module.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 はブートストラップ コンポーネントとして設定され、アプリケーションのエントリ ポイントになります。

app.component.ts

import { Component } from '@angular/core'

@Component({
  selector: 'app-root',
  template: `<router-outlet></router-outlet>`
})

export class AppComponent { }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

app.component.ts ファイルは、 を使用するルート コンポーネント AppComponent を定義します。ルート ビューを表示するには、テンプレート内のディレクティブを使用します。コンポーネントはアプリルート セレクターによって識別され、Angular アプリケーションのエントリ ポイントとして機能します。

app.interceptor.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<any>> {
    return next.handle(request.clone({
      url: this.baseURL + request.url,
    }))
  }
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

AppInterceptor クラスは、サーバーに送信される前に、すべての送信 HTTP リクエスト URL に構成可能な BaseURL を追加する Angular HTTP インターセプターです。これにより、アプリケーションはベース API エンドポイントを一元化し、簡単に管理できるようになります。

アプリルーティング.モジュール.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」にリダイレクトするルートも含まれています。

Create.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" (submit)="create()">
            <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" [(ngModel)]="product.Name" maxlength="50" />
                <span *ngIf="errors.name" 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" [(ngModel)]="product.Price" type="number" />
                <span *ngIf="errors.price" 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 を呼び出して製品を作成し、製品リストに戻ります。検証エラーは対応するフィールドの横に表示され、作成エラーがあるとアラートがトリガーされます。

コンポーネント.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、名前、価格を読み取り専用フィールドに表示します。このコンポーネントには、ナビゲーション用の「戻る」ボタンと「編集」ボタンが用意されています。製品の詳細は、コンポーネントの初期化時に取得されて表示されます。

Edit.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 を介して製品が更新され、製品リストに戻ります。取得または更新中のエラーはアラートとして表示され、検証エラーは関連フィールドの横に表示されます。

インデックス.コンポーネント.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<any>> {
    return next.handle(request.clone({
      url: this.baseURL + request.url,
    }))
  }
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

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 は、スタイル用の Bootstrap、アイコン用の Font Awesome、 など、Angular アプリケーションのメイン エントリ ポイントとして機能します。 Angular アプリのプレースホルダーとして使用します。

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))
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

このファイルには、データベースに接続するための構成の詳細が保持されます。

db.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 接続文字列を構築し、グローバル DB 変数に保存される GORM インスタンスを初期化します。

ルーター.ゴー

import { Component } from '@angular/core'

@Component({
  selector: 'app-root',
  template: `<router-outlet></router-outlet>`
})

export class AppComponent { }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この router.go ファイルは、Gin フレームワークを使用して Go アプリケーションのルーティングを設定します。 SetupRouter 関数は、CORS ミドルウェアを使用して Jin ルーターを初期化し、すべてのオリジンを許可します。 /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<any>> {
    return next.handle(request.clone({
      url: this.baseURL + request.url,
    }))
  }
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この product.go ファイルは、GORM で使用する製品モデルを定義します。これは、Id (自動インクリメント主キー)、Name、Price の 3 つのフィールドを持つ Product 構造体を指定します。

product_controller.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 ファイルは、Gin フレームワークを使用して Go アプリケーションで製品の CRUD 操作を処理するメソッドを含む ProductController 構造体を定義します。

  • Index すべての製品のリストを取得して返します。
  • Get は、ID に基づいて単一の製品を取得して返します。
  • Create リクエスト本文から新しい商品を作成します。
  • Update リクエスト本文のデータを使用して既存の製品を更新します。
  • 削除 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" (submit)="create()">
            <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" [(ngModel)]="product.Name" maxlength="50" />
                <span *ngIf="errors.name" 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" [(ngModel)]="product.Price" type="number" />
                <span *ngIf="errors.price" 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" (submit)="this.delete()">
            <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)
    })
  }
}
ログイン後にコピー

Web ブラウザを開いて http://localhost:4200 に移動します

こちらの商品一覧ページになります。

Building an Angular CRUD App with a Go API

テスト

「表示」ボタンをクリックすると、製品の詳細ページが表示されます。

Building an Angular CRUD App with a Go API

商品を変更し、詳細を更新するには、[編集] ボタンをクリックします。

Building an Angular CRUD App with a Go API

「送信」ボタンをクリックして、更新された製品の詳細を保存します。

Building an Angular CRUD App with a Go API

「作成」ボタンをクリックして新しい製品を追加し、その詳細を入力します。

Building an Angular CRUD App with a Go API

「送信」ボタンをクリックして新しい製品を保存します。

Building an Angular CRUD App with a Go API

以前に作成した製品を削除するには、[削除] ボタンをクリックします。

Building an Angular CRUD App with a Go API

この製品の削除を確認するには、[削除] ボタンをクリックしてください。

Building an Angular CRUD App with a Go API

結論

結論として、Gin フレームワークをバックエンドとして使用して API をセットアップしながら、コンポーネント、ビュー、ルーティングを含む基本的な Angular プロジェクトを作成する方法を学びました。データベース操作に GORM を利用することで、強力で効率的なバックエンドとシームレスに統合する動的なフロントエンドの構築に成功しました。この組み合わせにより、最新のフルスタック Web アプリケーションを開発するための強固な基盤が形成されます。

ソースコード: https://github.com/stackpuz/Example-CRUD-Angular-18-Go

Angular CRUD アプリを数分で作成: https://stackpuz.com

以上がGo API を使用した Angular CRUD アプリの構築の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!