开始使用 Angular
本集成指南遵循 快速入门指南,并假设您已完全完成“动手”路径。您应该能够通过浏览 URL http://localhost:1337/api/restaurants 来使用该 API。
如果您尚未阅读快速入门指南,则使用 Angular 请求 Strapi API 的方式保持不变,只是您不会获取相同的内容。
创建 Angular 应用
使用 angular CLI 创建基本的 Angular 应用。
bash
npx -p @angular/cli ng new angular-app
使用 Angular HTTP 客户端
导入 Angular HttpClientModule:
./src/app/app.module.ts
ts
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { HttpClientModule } from '@angular/common/http'
import { AppComponent } from './app.component'
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, HttpClientModule],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
GET 请求您的集合类型
对 restaurant
集合类型执行 GET
请求以获取您的所有餐厅。
确保您已激活 restaurant
集合类型的 find
权限。
Example GET request
ts
// this.http is the Angular HttpClient service.
this.http
.get('http://localhost:1337/api/restaurants', {
params: { populate: '*' },
})
.subscribe((response) => {
console.log(response)
})
Example response
json
{
"data": [
{
"id": 1,
"attributes": {
"name": "Biscotte Restaurant",
"description": "Welcome to Biscotte restaurant! Restaurant Biscotte offers a cuisine based on fresh, quality products, often local, organic when possible, and always produced by passionate producers.",
"createdAt": "2023-03-25T11:13:41.883Z",
"updatedAt": "2023-03-25T11:17:45.737Z",
"publishedAt": "2023-03-25T11:17:45.735Z",
"categories": {
"data": [
{
"id": 2,
"attributes": {
"name": "Brunch",
"createdAt": "2023-03-25T11:14:20.605Z",
"updatedAt": "2023-03-25T11:17:00.158Z",
"publishedAt": "2023-03-25T11:17:00.153Z"
}
}
]
}
}
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
}
Example
./src/app/app.component.ts
ts
import { HttpClient, HttpErrorResponse } from '@angular/common/http'
import { Component, OnInit } from '@angular/core'
import { Observable, catchError, map, of } from 'rxjs'
interface Restaurant {
name: string
description: string
}
interface Entry<T> {
id: number
attributes: T
}
interface Response {
data: Entry<Restaurant>[]
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
error: any | undefined
restaurants$: Observable<Restaurant[]> | undefined
constructor(private http: HttpClient) {}
ngOnInit(): void {
const url = 'http://localhost:1337/api/restaurants'
const opts = { params: { populate: '*' } }
this.restaurants$ = this.http.get<Response>(url, opts).pipe(
catchError(error => this.handleError(error)),
map(response => response.data.map(x => x.attributes))
)
}
private handleError(error: HttpErrorResponse): Observable<never> {
this.error = error
return of()
}
}
./src/app/app.component.html
html
<div *ngIf="error">{{error}}</div>
<ul *ngIf="restaurants$|async as restaurants">
<li *ngFor="let restaurant of restaurants">{{restaurant.name}}</li>
</ul>
POST 请求您的集合类型
对“restaurant”集合类型执行“POST”请求以创建餐厅。
确保您已激活“restaurant”集合类型的“create”权限和“category”集合类型的“find”权限。
在此示例中,已创建“japanese”类别,其 ID 为:3。
Example POST request with axios
ts
// this.http is the Angular HttpClient service.
this.http
.post('http://localhost:1337/api/restaurants', {
data: {
name: 'Dolemon Sushi',
description:
'Unmissable Japanese Sushi restaurant. The cheese and salmon makis are delicious',
categories: [3],
},
})
.subscribe((response) => {
console.log(response)
})
Response Example
json
{
"id": 2,
"name": "Dolemon Sushi",
"description": "Unmissable Japanese Sushi restaurant. The cheese and salmon makis are delicious",
"created_by": null,
"updated_by": null,
"created_at": "2020-08-04T09:57:11.669Z",
"updated_at": "2020-08-04T09:57:11.669Z",
"categories": [
{
"id": 3,
"name": "Japanese",
"created_by": 1,
"updated_by": 1,
"created_at": "2020-07-31T11:36:23.164Z",
"updated_at": "2020-07-31T11:36:23.172Z"
}
]
}
Example
./src/app/app.module.ts
ts
import { HttpClientModule } from '@angular/common/http'
import { NgModule } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { BrowserModule } from '@angular/platform-browser'
import { AppComponent } from './app.component'
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, FormsModule, HttpClientModule],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
./src/app/app.component.ts
ts
import { Component, OnInit } from '@angular/core'
import { FormArray, FormBuilder } from '@angular/forms'
import { Observable, catchError, map, of, tap } from 'rxjs'
import { HttpClient, HttpErrorResponse } from '@angular/common/http'
interface Category {
name: string
}
interface Entry<T> {
id: number
attributes: T
}
interface Response<T> {
data: Entry<T>[]
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
allCategories$: Observable<Entry<Category>[]> | undefined
error: any | undefined
modifiedData = {
name: '',
description: '',
categories: new Array<{ id: number, checked: boolean }>(),
}
constructor(private http: HttpClient) {}
ngOnInit(): void {
this.allCategories$ = this.http
.get<Response<Category>>('http://localhost:1337/api/categories')
.pipe(
catchError(error => this.handleError(error)),
map(response => response.data),
tap((data) => {
data.forEach((x) => {
this.modifiedData.categories.push({ id: x.id, checked: false })
})
})
)
}
onSubmit(): void {
const body = {
data: {
name: this.modifiedData.name,
description: this.modifiedData.description,
categories: this.modifiedData.categories
.filter(x => x.checked)
.map(x => x.id),
},
}
this.http
.post('http://localhost:1337/api/restaurants', body)
.pipe(catchError(error => this.handleError(error)))
.subscribe((response) => {
console.log(response)
this.resetForm()
})
}
private handleError(error: HttpErrorResponse): Observable<never> {
this.error = error.message
return of()
}
private resetForm(): void {
this.modifiedData.name = ''
this.modifiedData.description = ''
this.modifiedData.categories.forEach(x => (x.checked = false))
}
}
./src/app/app.component.html
html
<div *ngIf="error">{{error}}</div>
<form (ngSubmit)="onSubmit()">
<div>
<label for="name"> Name </label>
<input name="name" type="text" [(ngModel)]="modifiedData.name" />
</div>
<div>
<label for="address"> Description </label>
<input
name="description"
type="text"
[(ngModel)]="modifiedData.description"
/>
</div>
<div *ngIf="allCategories$ | async as allCategories">
<br />
Select categories
<div *ngFor="let category of allCategories; index as i">
<label
>{{category.attributes.name}}
<input
type="checkbox"
name="category{{i}}"
[(ngModel)]="modifiedData.categories[i].checked"
/>
</label>
</div>
</div>
<button class="button" type="submit">Create</button>
</form>
PUT 请求您的集合类型
对 restaurant
集合类型执行 PUT
请求,以更新餐厅的类别。
确保您已为 restaurant
集合类型激活 put
权限。
我们认为您的餐厅的 ID 为 2
。
您的类别的 ID 为 2
。
Example PUT request
ts
// this.http is the Angular HttpClient service.
this.http
.put('http://localhost:1337/api/restaurants/2', {
data: {
categories: [2],
},
})
.subscribe((response) => {
console.log(response)
})
Example response
json
{
"id": 2,
"attributes": {
"name": "Dolemon Sushi",
"description": "Unmissable Japanese Sushi restaurant. The cheese and salmon makis are delicious",
"created_by": null,
"updated_by": null,
"created_at": "2020-08-04T10:21:30.219Z",
"updated_at": "2020-08-04T10:21:30.219Z",
"categories": [
{
"id": 2,
"name": "Brunch",
"created_by": 1,
"updated_by": 1,
"created_at": "2020-08-04T10:24:26.901Z",
"updated_at": "2020-08-04T10:24:26.911Z"
}
]
}
}