【发布时间】:2022-01-28 01:42:23
【问题描述】:
我的旅行表列表显示除了图像封面之外的所有必需信息。我无法弄清楚为什么图像路径被破坏了。我怀疑我的后端代码为我的静态文件提供服务,但据我所知,一切似乎都很好。
在后端代码中,我有以下代码行用于在我的 app.js 文件中提供静态文件。
app.use(
'/public/img/countries',
express.static(`${__dirname}/public/img/countries`)
);
app.use('/public/img/tours', express.static(`${__dirname}/public/img/tours`));
app.use('/public/img/users', express.static(`${__dirname}/public/img/users`));
在我的游览处理程序函数 tourController.js 后端代码中,我有以下代码,因为它专门与图像有关。
const multerStorage = multer.memoryStorage();
const multerFilter = (req, file, cb) => {
if (file.mimetype.startsWith('image')) {
cb(null, true);
} else {
cb(new AppError('Not an image! Please upload only images.', 400), false);
}
};
const upload = multer({
storage: multerStorage,
fileFilter: multerFilter
// limits: { fileSize: maxSize }
});
exports.uploadTourImages = upload.fields([
//req.files for fields
{ name: 'imageCover', maxCount: 1 },
{ name: 'images', maxCount: 3 }
]);
exports.resizeTourImages = catchAsync(async (req, res, next) => {
if (!req.files.imageCover || !req.files.images) return next();
// 1) Cover image
req.body.imageCover = `tour-${req.params.id}-${Date.now()}-cover.jpeg`;
await sharp(req.files.imageCover[0].buffer)
.rotate()
.resize(1903, 1268)
.toFormat('jpeg')
.jpeg({ quality: 90 })
.toFile(`public/img/tours/${req.body.imageCover}`);
req.body.images = [];
await Promise.all(
req.files.images.map(async (file, i) => {
const filename = `tour-${req.params.id}-${Date.now()}-${i + 1}.jpeg`;
await sharp(file.buffer)
.rotate()
.resize(1903, 1268)
.toFormat('jpeg')
.jpeg({ quality: 90 })
.toFile(`public/img/tours/${filename}`);
req.body.images.push(filename);
})
);
next();
});
在我的后端模型上的工厂函数
exports.getAll = Model =>
catchAsync(async (req, res, next) => {
let filter = {};
if (req.params.tourId) filter = { tour: req.params.tourId };
//EXECUTE QUERY
const features = new APIFeatures(Model.find(filter), req.query)
.filter()
.sort()
.limitFields()
.paginate();
const doc = await features.query;
//SEND REPONSE
res.status(200).json({
status: 'success',
results: doc.length,
data: {
data: doc
}
});
next();
});
在我的前端,我的 tour-list.component.html 上有下面的表格代码
<p-table [value]="tours" styleClass="p-datatable-gridlines" responsiveLayout="scroll">
<ng-template pTemplate="header">
<tr>
<th pSortableColumn="name">Name<p-sortIcon field="name"></p-sortIcon></th>
<th>Image Cover</th>
<th pSortableColumn="price">Price<p-sortIcon field="price"></p-sortIcon></th>
<th pSortableColumn="ratingsAverage">
Ratings Average <p-sortIcon field="ratingsAverage"></p-sortIcon>
</th>
<th pSortableColumn="country">Country<p-sortIcon field="country"></p-sortIcon></th>
<th pSortableColumn="difficulty">
Difficulty<p-sortIcon field="difficulty"></p-sortIcon>
</th>
<th pSortableColumn="availabilityDates">
Availability Dates<p-sortIcon field="availabilityDates"></p-sortIcon>
</th>
<th pSortableColumn="maxGroupPair">
Maximum Group Pairs<p-sortIcon field="maxGroupPair"></p-sortIcon>
</th>
<th pSortableColumn="minimumAge">
Minimum Age<p-sortIcon field="minimumAge"></p-sortIcon>
</th>
<th pSortableColumn="dateCreated">
Date Created<p-sortIcon field="dateCreated"></p-sortIcon>
</th>
<th></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-tour>
<tr>
<td>{{ tour.name }}</td>
<td><img [src]="tour.imageCover" width="100px" height="67px" alt="" /></td>
<td>{{ tour.price }}</td>
<td>{{ tour.ratingsAverage }}</td>
<td>{{ tour.country.name }}</td>
<td>{{ tour.difficulty }}</td>
<td>{{ tour.availabilityDates }}</td>
<td>{{ tour.maxGroupPair }}</td>
<td>{{ tour.minimumAge }}</td>
<td>{{ tour.dateCreated | date: 'longDate' }}</td>
</tr>
</ng-template>
</p-table>
我的 tours-list.component.ts 文件有以下代码
import { Component, OnInit } from '@angular/core';
import { ToursService } from '@tourafrika/tours';
@Component({
selector: 'admin-tours-list',
templateUrl: './tours-list.component.html',
styles: []
})
export class ToursListComponent implements OnInit {
tours = [];
constructor(private tourService: ToursService) {}
ngOnInit(): void {
this._getTours();
}
private _getTours() {
this.tourService.getTours().subscribe((tours) => {
this.tours = tours;
});
}
}
我前端的库模型代码具有以下代码。
import { Country } from './country';
import { User } from './user';
export class Tour {
id?: string;
name?: string;
slug?: string;
country?: Country;
duration?: number;
maxGroupPair?: number;
singleSupplement?: number;
difficulty?: string;
ratingsAverage?: number;
ratingsQuantity?: number;
price?: number;
priceDiscount?: number;
overview?: string;
imageCover?: string;
images?: string[];
dateCreated?: string;
availabilityDates?: string[];
isFeatured?: boolean;
secretTour?: string;
minimumAge?: string;
departureLocation?: string;
locations?: string;
guides?: [User];
}
export interface ITourListResponse {
status: string;
results: number;
data: { data: Tour[] };
}
我的 tours.service.ts 服务文件有以下代码。
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Tour, ITourListResponse } from '../models/tour';
import { map } from 'rxjs/operators';
import { environment } from '@env/environment';
@Injectable({
providedIn: 'root'
})
export class ToursService {
apiURLTours = environment.apiUrl + 'tours';
constructor(private http: HttpClient) {}
getTours(): Observable<Tour[]> {
return this.http
.get<ITourListResponse>(this.apiURLTours)
.pipe(map((response: ITourListResponse) => response.data.data));
}
谢谢!
【问题讨论】:
-
请分享您的 API 响应数据。
-
API 响应非常大,但与 Image Cove 相关的是:{ "status": "success", "results": 12, "data": { "data": [ " imageCover": "tour-61df1a042001bcc1821b17d6-1643097859361-cover.jpeg", ] }
-
我正在通过私有 _getTours() 方法在我的 tours-list.component.ts 文件上运行 console.log(this.tours) 获取所有数据并提取 console.log(this.tours ) 带有显示 imageCover 的图像封面的数组:“tour-61df19e82001bcc1821b17cc-1643098212886-cover.jpeg”
-
您是否将这些图像包含在您的前端资产文件夹中?
-
不,我没有。我只是通过 Postman 的更新使用我的后端代码上传了这些图像。 .现在我只想获取数据库中的一些数据字段,并通过运行私有 _getTours 用这些数据填充前端。除了封面图片路径损坏之外,所有数据都通过前端。
标签: node.js angular typescript express