我想创建一个包含 6 个页面的 Ionic 2 应用程序,我不确定是对各个类别页面使用 Pipe 还是 Filter 以及我需要这样做的代码。
每个类别页面可以加载“applecat”类别定义的相关产品。下面是 API,通过 Google 表格以电子表格格式显示产品,以及一个非常快速的主页模型创意:
https://sheetsu.com/apis/v1.0/04c2d2906a10 https://docs.google.com/spreadsheets/d/1RNLXsxTFymqRwq_S538qX1p1PAEDIEA6s5sV8etkfLU/edit?usp=sharing
概述
6 页
- 主页 - 无需加载任何产品 - 只需链接到页面
- allproducts - 加载所有产品
- ipad - 加载 applecat 类别下列为 ipad 的所有项目
- iphone - 加载 applecat 类别下列为 iphone 的所有项目
- 键盘 - 加载 applecat 类别下列为 iphone 的所有项目
- laptop - 加载 applecat 类别下列为 iphone 的所有项目
场景(潜在用户流)
用户打开应用程序,点击主页,然后点击 Ipad 类别链接(加载所有 Ipad 产品) 然后回到首页决定点击All(Loads ALL products),返回并点击另一个页面....
问题
它会加载 2 个数组到内存/控制台吗? 类别页面应该使用过滤器还是管道?代码应如何查找与我现有的 API 调用和产品列表数组相关的管道/过滤器?
vendor
getRemoteData(): any{
return this.http.get('https://sheetsu.com/apis/v1.0/04c2d2906a10')
.map(res => res.json());
}
列表页
@Component({
selector: 'page-master',
templateUrl: 'master.html',
providers: [Sheetsu]
})
export class MasterPage {
// declare publicly accessible variable
public sheetsuData: any;
constructor(public navCtrl: NavController, public navParams: NavParams, public sheetsuService: Sheetsu) {}
ionViewDidLoad() {
this.sheetsuService.getRemoteData()
.subscribe(response => {
// assign variable (async)
this.sheetsuData = response;
});
}
我看到了一个带有重置的过滤器示例,但不确定它是否适用于这种情况?
resetData(){
this.modifiedData = JSON.parse(JSON.stringify(this.originalData));
}
filterData(){
this.modifiedData = this.modifiedData.filter((youtuber) => {
return youtuber.subscribers > 1000000;
}
}
对于如此少的类别页面,也许 Pipe 是每个页面的最佳选择?如果用户浏览所有 6 个页面,则只是多个 API 调用的潜在问题。
首选赏金答案:管道/过滤器/服务的代码,关于最佳解决方案的建议及其原因,甚至更好的是 Github 中的基本工作示例(上面提供了对提供程序和列表 ts 代码的 API 调用)。
可以从 https://github.com/jones98/4cat 查看和 fork 此内容的 Github 存储库
可以在 https://drive.google.com/file/d/0B0QBawqyq1vPZ0o4WEpaa0o0azQ/view 查看当前状态下应用程序的视频(预分类页面工作)
最佳答案
您可以创建一个缓存数据的服务(可能是 5 分钟、30 分钟、1 小时,或任何在您的应用程序上下文中有意义的时间间隔)以避免发出如此多的 http 请求,并且将也只返回你需要的东西,这样你就可以直接在组件/ View 中使用它,而不需要过滤任何东西。
这不仅会减少对服务器发出的大量无用的 http 请求,而且还会使应用速度更快,因为用户打开产品页面的大部分时间都将使用本地数据。
假设您已经有一个产品类:
export class ProductModel {
public aw_deep_link: string;
public product_name: string;
public apple_cat: string;
//...
}
然后我们可以像这样创建我们的缓存模型:
class ProductCache {
public products: Array<ProductModel>;
public timestamp: number;
public isValid(): boolean {
if(!this.products) {
return false;
}
let isExpired = Date.now() - this.timestamp > 1800000; // 30 min
return !isExpired;
}
}
然后我们可以在我们的 ProductCategoryService 中使用它
// Angular imports
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
// Rxjs imports
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';
@Injectable()
export class ProductCategoryService {
private cache: ProductCache;
private apiUrl: string = 'https://sheetsu.com/apis/v1.0/04c2d2906a10';
constructor(private http: Http) {
this.cache = new ProductCache();
}
public getAll(): Observable<Array<ProductModel>> {
if(this.cache.isValid()) {
// Return the products from the cache
return Observable.of(this.cache.products);
}
// Cache is empty/expired, so we need to make the http request
return this.http.get(this.apiUrl).map(res => res.json()).map(data => {
// Save the data in the cache for the next time
this.cache.products = data;
this.cache.timestamp = Date.now();
// Return the list of (all) products
return this.cache.products;
});
}
public getIpadProducts(): Observable<Array<ProductModel>> {
return this.getAll().filter((product: ProductModel) => {
return product.apple_cat.toLowerCase() === 'ipad';
});
}
public getIphoneProducts(): Observable<Array<ProductModel>> {
return this.getAll().filter((product: ProductModel) => {
return product.apple_cat.toLowerCase() === 'iphone';
});
}
// ...
}
然后只需在每个页面中调用正确的方法,由于产品的缓存,http 请求只会发出一次(或在本例中为每 30 分钟一次)。
可能存在语法错误或拼写错误(我直接在 SO 答案中编码),但这应该让您了解如何处理给定的场景。如果有什么地方不能正常工作,请告诉我,以便我可以帮助您解决问题...
更新:Here您可以找到一些信息(来自 Angular 2 Docs),说明为什么使用管道过滤数据不是一个很好的方法,这就是为什么我建议在服务中这样做,对其他人保持隐藏应用程序的(毕竟,每个类别页面只是想获得它需要显示的数据,它不应该处理所有产品然后只找到它需要在 View 中显示的产品)。
关于javascript - 使用过滤器或管道将产品类别加载到 Ionic 2 的页面中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42139522/