> 백엔드 개발 > Golang > Go API를 사용하여 Angular CRUD 앱 구축

Go API를 사용하여 Angular CRUD 앱 구축

Patricia Arquette
풀어 주다: 2024-11-04 21:36:02
원래의
484명이 탐색했습니다.

Building an Angular CRUD App with a Go API

CRUD 작업(생성, 읽기, 업데이트, 삭제)은 대부분의 웹 애플리케이션의 백본입니다. 이 튜토리얼에서는 프런트엔드에 Angular를 사용하고 백엔드에 GoAPI를 사용하여 CRUD 앱을 구축하여 완전히 통합되고 효율적인 전체 스택 솔루션을 만드는 방법을 보여줍니다.

전제 조건

  • Node.js
  • 1.21로 이동
  • MySQL

각도 프로젝트 설정

Angular 18을 설치하고 다음 명령을 사용하여 새 프로젝트를 만듭니다.

npm install -g @angular/cli@18.0.0
ng new view --minimal --routing --style css --no-standalone --ssr=false
로그인 후 복사
로그인 후 복사
로그인 후 복사

각도 프로젝트 구조

└─ 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
로그인 후 복사
로그인 후 복사
로그인 후 복사

*이 프로젝트 구조에는 생성하거나 수정하려는 파일과 폴더만 표시됩니다.

각도 프로젝트 파일

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.comComponent.ts

import { Component } from '@angular/core'

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

export class AppComponent { }
로그인 후 복사
로그인 후 복사
로그인 후 복사

app.comComponent.ts 파일은 라우팅된 뷰를 표시하는 템플릿의 지시어입니다. 구성 요소는 app-root 선택기로 식별되며 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 엔드포인트를 중앙 집중화하고 쉽게 관리할 수 있습니다.

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은 제품 나열, 생성, 보기, 편집 및 삭제를 위한 제품 관련 경로를 포함하여 Angular 애플리케이션에 대한 라우팅을 설정합니다. 루트 경로 "/"에서 제품 목록 페이지 "/product"로 리디렉션되는 경로도 포함되어 있습니다.

Create.comComponent.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.comComponent.ts의 ProductDelete 구성 요소는 제품 삭제를 처리하는 Angular 구성 요소입니다. 제품 세부 정보(ID, 이름 및 가격)를 표시하는 읽기 전용 필드가 있는 양식을 표시합니다. 구성 요소가 초기화되면 경로의 제품 ID를 사용하여 제품 세부 정보를 가져옵니다. 양식 제출 시 delete() 메소드는 ProductService를 호출하여 제품을 삭제한 다음 제품 목록으로 리디렉션합니다. 삭제 중 오류가 발생하면 알림이 표시됩니다.

Detail.comComponent.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.comComponent.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를 통해 제품을 업데이트하고 제품 목록으로 다시 이동합니다. 가져오거나 업데이트하는 동안 오류가 발생하면 경고로 표시되며, 유효성 검사 오류는 해당 필드 옆에 표시됩니다.

Index.comComponent.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, 이름, 가격을 표시합니다. 또한 제품 생성 페이지로 이동하는 버튼도 포함되어 있습니다.

Product.service.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는 컨테이너 위에 공간을 추가하고 버튼을 수평으로 간격을 두어 레이아웃을 조정합니다.

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은 스타일 지정을 위한 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 인스턴스를 초기화합니다.

router.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 서버가 시작됩니다.

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,
    }))
  }
}
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 product.go 파일은 GORM과 함께 사용할 제품 모델을 정의합니다. Id(자동 증가 기본 키), 이름, 가격의 세 가지 필드가 있는 제품 구조를 지정합니다.

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는 모든 제품의 목록을 검색하고 반환합니다.
  • 가져오기를 받고 해당 ID로 단일 제품을 반환합니다.
  • 생성 요청 본문에서 새 제품을 생성합니다.
  • 업데이트 요청 본문의 데이터로 기존 제품을 업데이트합니다.
  • 삭제 해당 ID별로 제품을 삭제합니다.

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)
    })
  }
}
로그인 후 복사
로그인 후 복사

이 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)
    })
  }
}
로그인 후 복사

웹 브라우저를 열고 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을 활용하여 강력하고 효율적인 백엔드와 완벽하게 통합되는 동적 프런트엔드를 성공적으로 구축했습니다. 이 조합은 최신 풀스택 웹 애플리케이션 개발을 위한 견고한 기반을 형성합니다.

소스 코드: https://github.com/stackpuz/Example-CRUD-Angular-18-Go

몇 분 만에 Angular CRUD 앱 만들기: https://stackpuz.com

위 내용은 Go API를 사용하여 Angular CRUD 앱 구축의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿