使用过滤器或管道将产品类别加载到 Ionic 2 的页面中?
Use a filter or pipe to load product categories into pages in Ionic 2?
我想创建一个有 6 个页面的 Ionic 2 应用程序,我不确定是对各个类别页面使用管道还是过滤器以及我需要这样做的代码。
每个分类页面可以加载"applecat"分类定义的相关产品。下面是 API,通过 Google 表格以电子表格格式显示产品和一个非常快速的主页模型想法:
https://sheetsu.com/apis/v1.0/04c2d2906a10
https://docs.google.com/spreadsheets/d/1RNLXsxTFymqRwq_S538qX1p1PAEDIEA6s5sV8etkfLU/edit?usp=sharing
概览
6 页
- 主页 - 无需加载任何产品 - 只需 link 页面
- allproducts - 加载所有产品
- ipad - 加载 applecat 类别
下列为 ipad 的所有项目
- iphone - 加载 applecat 类别
下列为 iphone 的所有项目
- 键盘 - 加载 applecat 类别
下列为 iphone 的所有项目
- laptop -加载 applecat 类别
下列为 iphone 的所有项目
场景(潜在用户流)
用户打开应用程序,点击主页,然后点击 Ipad 类别 link(加载所有 Ipad 产品)
然后回到首页决定点击All(Loads ALL products),返回并点击另一个页面....
问题
它会将 2 个数组加载到 memory/console 中吗?
类别页面应该使用过滤器还是管道?代码应如何查找与我现有的 API 调用和产品列表数组相关的 pipe/filter?
提供商
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 调用的潜在问题。
首选赏金答案:pipe/filter/service 的代码,关于最佳解决方案的建议及其原因,更好的是 Github 中的基本工作示例(API 调用对于提供商和列表 ts 代码在上面)。
Github 可以从 https://github.com/jones98/4cat
查看和分叉此 repo
可以在 https://drive.google.com/file/d/0B0QBawqyq1vPZ0o4WEpaa0o0azQ/view
查看当前状态下的应用视频(预分类页面工作)
您可以创建一个缓存数据的服务(可能是 5 分钟、30 分钟、1 小时或任何在您的应用程序上下文中有意义的时间间隔)以避免发出如此多的 http 请求,并且还将 return 只包含您需要的内容,因此您可以直接在 component/view 中使用它,而无需过滤任何内容。
这不仅会减少对服务器发出的大量无用的 http 请求,而且还会使应用程序运行得更快,因为用户打开产品页面的大部分时间都将使用本地数据。
假设您已经有一个 class 的产品:
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 答案中编码),但这应该让您了解如何处理给定的场景。如果有什么地方不能正常工作,请告诉我,这样我可以帮你修复它...
UPDATE: Here 你可以找到一些信息(来自 Angular 2 Docs)关于为什么使用管道过滤数据不是一个很好的方法,这就是为什么我建议在服务中这样做,将它 隐藏 应用程序的其余部分(毕竟,每个类别页面只想获取它需要显示的数据,它不必处理所有产品,然后只找到需要在视图中显示的产品)。
我还应该创建一个名为 ProductCategoryService
的服务
ionic g provider ProductCategory
并创建一个我可以使用类别名称作为参数执行的方法
getProductsByCategoryName(categoryName): any{
return this.allProducts.filter(product => product.categoryName === categoryName);
}
在 return 中,我将使用我的产品获得一个过滤数组,将其绑定到您的模板即可完成。
我想创建一个有 6 个页面的 Ionic 2 应用程序,我不确定是对各个类别页面使用管道还是过滤器以及我需要这样做的代码。
每个分类页面可以加载"applecat"分类定义的相关产品。下面是 API,通过 Google 表格以电子表格格式显示产品和一个非常快速的主页模型想法:
https://sheetsu.com/apis/v1.0/04c2d2906a10 https://docs.google.com/spreadsheets/d/1RNLXsxTFymqRwq_S538qX1p1PAEDIEA6s5sV8etkfLU/edit?usp=sharing
概览
6 页
- 主页 - 无需加载任何产品 - 只需 link 页面
- allproducts - 加载所有产品
- ipad - 加载 applecat 类别 下列为 ipad 的所有项目
- iphone - 加载 applecat 类别 下列为 iphone 的所有项目
- 键盘 - 加载 applecat 类别 下列为 iphone 的所有项目
- laptop -加载 applecat 类别 下列为 iphone 的所有项目
场景(潜在用户流)
用户打开应用程序,点击主页,然后点击 Ipad 类别 link(加载所有 Ipad 产品) 然后回到首页决定点击All(Loads ALL products),返回并点击另一个页面....
问题
它会将 2 个数组加载到 memory/console 中吗? 类别页面应该使用过滤器还是管道?代码应如何查找与我现有的 API 调用和产品列表数组相关的 pipe/filter?
提供商
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 调用的潜在问题。
首选赏金答案:pipe/filter/service 的代码,关于最佳解决方案的建议及其原因,更好的是 Github 中的基本工作示例(API 调用对于提供商和列表 ts 代码在上面)。
Github 可以从 https://github.com/jones98/4cat
查看和分叉此 repo可以在 https://drive.google.com/file/d/0B0QBawqyq1vPZ0o4WEpaa0o0azQ/view
查看当前状态下的应用视频(预分类页面工作)您可以创建一个缓存数据的服务(可能是 5 分钟、30 分钟、1 小时或任何在您的应用程序上下文中有意义的时间间隔)以避免发出如此多的 http 请求,并且还将 return 只包含您需要的内容,因此您可以直接在 component/view 中使用它,而无需过滤任何内容。
这不仅会减少对服务器发出的大量无用的 http 请求,而且还会使应用程序运行得更快,因为用户打开产品页面的大部分时间都将使用本地数据。
假设您已经有一个 class 的产品:
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 答案中编码),但这应该让您了解如何处理给定的场景。如果有什么地方不能正常工作,请告诉我,这样我可以帮你修复它...
UPDATE: Here 你可以找到一些信息(来自 Angular 2 Docs)关于为什么使用管道过滤数据不是一个很好的方法,这就是为什么我建议在服务中这样做,将它 隐藏 应用程序的其余部分(毕竟,每个类别页面只想获取它需要显示的数据,它不必处理所有产品,然后只找到需要在视图中显示的产品)。
我还应该创建一个名为 ProductCategoryService
的服务ionic g provider ProductCategory
并创建一个我可以使用类别名称作为参数执行的方法
getProductsByCategoryName(categoryName): any{
return this.allProducts.filter(product => product.categoryName === categoryName);
}
在 return 中,我将使用我的产品获得一个过滤数组,将其绑定到您的模板即可完成。