Rumah >pembangunan bahagian belakang >Golang >Membina Apl CRUD Sudut dengan API Go

Membina Apl CRUD Sudut dengan API Go

Patricia Arquette
Patricia Arquetteasal
2024-11-04 21:36:02485semak imbas

Building an Angular CRUD App with a Go API

Operasi CRUD (Buat, Baca, Kemas Kini, Padam) ialah tulang belakang kebanyakan aplikasi web. Dalam tutorial ini, kami akan menunjukkan kepada anda cara membina apl CRUD dengan Angular di bahagian hadapan dan GoAPI di bahagian belakang, menghasilkan penyelesaian tindanan penuh bersepadu dan cekap.

Prasyarat

  • Node.js
  • Pergi 1.21
  • MySQL

Sediakan projek Sudut

Pasang Angular 18 dan buat projek baharu dengan arahan berikut.

npm install -g @angular/cli@18.0.0
ng new view --minimal --routing --style css --no-standalone --ssr=false

Struktur projek sudut

└─ 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

*Struktur projek ini akan memaparkan hanya fail dan folder yang kami merancang untuk mencipta atau mengubah suai.

Fail Projek Sudut

utama.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))

Fail main.ts ini memulakan aplikasi Sudut dengan bootstrap AppModule menggunakan fungsi platformBrowserDynamic. Ia menyediakan aplikasi untuk dijalankan dalam penyemak imbas dan mengendalikan sebarang ralat yang berlaku semasa proses bootstrap.

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 ialah modul utama aplikasi Sudut. Ia mengimport modul teras Sudut dan menyediakan penghalaan dengan AppRoutingModule. Modul ini mengisytiharkan pelbagai komponen berkaitan produk. Ia juga mendaftarkan AppInterceptor sebagai pemintas HTTP. AppComponent ditetapkan sebagai komponen bootstrap, menjadikannya titik masuk aplikasi.

app.component.ts

import { Component } from '@angular/core'

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

export class AppComponent { }

Fail app.component.ts mentakrifkan komponen akar, AppComponent, yang menggunakan arahan dalam templatnya untuk memaparkan pandangan yang dihalakan. Komponen dikenal pasti oleh pemilih akar apl dan berfungsi sebagai titik masuk untuk aplikasi Sudut.

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,
    }))
  }
}

Kelas AppInterceptor ialah pemintas HTTP Sudut yang menambahkan baseURL boleh dikonfigurasikan pada semua URL permintaan HTTP keluar sebelum ia dihantar ke pelayan. Ini membolehkan aplikasi memusatkan dan mengurus titik akhir API asas dengan mudah.

app-routing.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 menyediakan penghalaan untuk aplikasi Sudut, termasuk laluan berkaitan produk untuk menyenaraikan, mencipta, melihat, mengedit dan memadamkan produk. Ia juga termasuk laluan yang mengubah hala dari laluan akar "/" ke halaman penyenaraian produk "/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)
    })
  }
}

Komponen ProductCreate menyediakan borang untuk mencipta produk baharu, mengikat medan input untuk nama dan harga pada objek produk. Semasa penyerahan, ia memanggil ProductService untuk mencipta produk dan menavigasi kembali ke senarai produk. Ralat pengesahan dipaparkan di sebelah medan yang sepadan dan sebarang ralat penciptaan mencetuskan makluman.

Delete.component.ts

npm install -g @angular/cli@18.0.0
ng new view --minimal --routing --style css --no-standalone --ssr=false

Komponen ProductDelete dalam Delete.component.ts ialah komponen Sudut yang mengendalikan pemadaman produk. Ia memaparkan borang dengan medan baca sahaja yang menunjukkan butiran produk (ID, nama dan harga). Apabila komponen dimulakan, ia mengambil butiran produk menggunakan ID produk daripada laluan. Semasa penyerahan borang, kaedah delete() memanggil ProductService untuk memadamkan produk dan kemudian mengubah hala ke senarai produk. Jika terdapat ralat semasa pemadaman, amaran ditunjukkan.

Detail.component.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

Komponen ProductDetail memaparkan butiran produk tertentu. Ia mendapatkan semula maklumat produk berdasarkan ID daripada laluan dan menunjukkan ID, nama dan harga produk dalam medan baca sahaja. Komponen ini menyediakan butang "Kembali" dan "Edit" untuk navigasi. Butiran produk diambil dan dipaparkan apabila komponen dimulakan.

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))

Komponen ProductEdit membolehkan pengguna mengedit produk sedia ada. Ia mendapatkan semula butiran produk menggunakan ID produk daripada laluan dan memaparkannya dalam bentuk dengan medan boleh diedit untuk nama dan harga. Semasa penyerahan borang, ia mengemas kini produk melalui ProductService dan menavigasi kembali ke senarai produk. Sebarang ralat semasa mengambil atau mengemas kini ditunjukkan sebagai makluman dan ralat pengesahan dipaparkan di sebelah medan yang berkaitan.

Index.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 { }

Komponen ProductIndex memaparkan senarai produk dalam format jadual. Ia mengambil senarai produk daripada ProductService pada permulaan dan menunjukkan ID, nama dan harga setiap produk, dengan butang tindakan untuk melihat, mengedit dan memadam setiap produk. Ia juga termasuk butang untuk menavigasi ke halaman penciptaan produk.

Product.service.ts

import { Component } from '@angular/core'

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

export class AppComponent { }

ProductService menggunakan HttpClient Angular untuk melaksanakan permintaan HTTP yang berkaitan untuk pengurusan produk. Ia menyediakan kaedah untuk:

  • get(id?): Ambil butiran produk melalui ID atau senarai produk jika tiada ID diberikan.
  • create(data?): Cipta produk baharu jika data disediakan, jika tidak, ambil halaman cipta produk.
  • edit(id, data?): Kemas kini produk mengikut ID jika data disediakan, jika tidak, dapatkan butiran produk untuk diedit.
  • delete(id, data?): Padamkan produk dengan ID jika data disediakan, jika tidak, dapatkan butiran produk untuk pengesahan.

styles.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 melaraskan reka letak dengan menambah ruang di atas bekas dan menjarakkan butang secara mendatar.

index.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 berfungsi sebagai titik masuk utama untuk aplikasi Sudut, termasuk Bootstrap untuk penggayaan, Font Awesome untuk ikon dan sebagai pemegang tempat untuk apl Sudut.

Sediakan projek API Go

npm install -g @angular/cli@18.0.0
ng new view --minimal --routing --style css --no-standalone --ssr=false

Buat pangkalan data ujian bernama "contoh" dan laksanakan fail database.sql untuk mengimport jadual dan data.

Struktur Projek API Go

└─ 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

Fail Projek API Go

.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))

Fail ini menyimpan butiran konfigurasi untuk menyambung ke pangkalan data.

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 { }

Fail db.go ini mengkonfigurasi sambungan pangkalan data dengan GORM. Fungsi SetupDatabase memuatkan pembolehubah persekitaran, membina rentetan sambungan MySQL dan memulakan tika GORM, yang disimpan dalam pembolehubah DB global.

router.go

import { Component } from '@angular/core'

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

export class AppComponent { }

Fail router.go ini menyediakan penghalaan untuk aplikasi Go menggunakan rangka kerja Gin. Fungsi SetupRouter memulakan penghala Gin dengan perisian tengah CORS untuk membenarkan semua asal. Ia mentakrifkan laluan untuk mengendalikan operasi berkaitan produk di bawah laluan /api/products, setiap satu dipetakan kepada kaedah dalam ProductController. Akhirnya, ia memulakan pelayan Gin.

product.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,
    }))
  }
}

Fail product.go ini mentakrifkan model Produk untuk digunakan dengan GORM. Ia menentukan struktur Produk dengan tiga medan: Id (kunci utama yang meningkat secara automatik), Nama, Harga.

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 { }

Fail product_controller.go mentakrifkan struct ProductController dengan kaedah untuk mengendalikan operasi CRUD untuk produk dalam aplikasi Go menggunakan rangka kerja Gin.

  • Indeks Mengambil dan mengembalikan senarai semua produk.
  • Dapatkan Ambil dan pulangkan satu produk dengan IDnya.
  • Cipta Mencipta produk baharu daripada badan permintaan.
  • Kemas Kini Mengemas kini produk sedia ada dengan data daripada badan permintaan.
  • Padam Memadamkan produk dengan IDnya.

main.go

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)
    })
  }
}

Fail main.go ini ialah titik masuk untuk aplikasi Go. Ia mengimport pakej konfigurasi dan penghalaan, kemudian memanggil config.SetupDatabase()untuk memulakan sambungan pangkalan data dan penghala.SetupRouter() untuk menyediakan laluan aplikasi.

Jalankan projek

Jalankan projek 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)
    })
  }
}

Jalankan projek API Go

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)
    })
  }
}

Buka pelayar web dan pergi ke http://localhost:4200

Anda akan menemui halaman senarai produk ini.

Building an Angular CRUD App with a Go API

Menguji

Klik butang "Lihat" untuk melihat halaman butiran produk.

Building an Angular CRUD App with a Go API

Klik butang "Edit" untuk mengubah suai produk dan mengemas kini butirannya.

Building an Angular CRUD App with a Go API

Klik butang "Serah" untuk menyimpan butiran produk yang dikemas kini.

Building an Angular CRUD App with a Go API

Klik butang "Buat" untuk menambah produk baharu dan masukkan butirannya.

Building an Angular CRUD App with a Go API

Klik butang "Serah" untuk menyimpan produk baharu.

Building an Angular CRUD App with a Go API

Klik butang "Padam" untuk mengalih keluar produk yang dibuat sebelum ini.

Building an Angular CRUD App with a Go API

Klik butang "Padam" untuk mengesahkan penyingkiran produk ini.

Building an Angular CRUD App with a Go API

Kesimpulan

Kesimpulannya, kami telah mempelajari cara mencipta projek Sudut asas dengan komponen, pandangan dan penghalaan, sambil menyediakan API menggunakan rangka kerja Gin sebagai bahagian belakang. Dengan menggunakan GORM untuk operasi pangkalan data, kami telah berjaya membina bahagian hadapan dinamik yang disepadukan dengan lancar dengan bahagian belakang yang berkuasa dan cekap. Gabungan ini membentuk asas yang kukuh untuk membangunkan aplikasi web tindanan penuh moden.

Kod sumber: https://github.com/stackpuz/Example-CRUD-Angular-18-Go

Buat Apl CRUD Sudut dalam Minit: https://stackpuz.com

Atas ialah kandungan terperinci Membina Apl CRUD Sudut dengan API Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn