所以我正在按照本教程学习如何为 Ionic 2 构建火种卡。本教程使用了randomuser.me的API,但我想使用我自己的JSON文件。
下面是我的打字稿文件(尽管我省略了一些不相关的代码片段(,最底部的函数是我更改的内容,以尝试检索我自己的 JSON 数据,但它无法正常工作:(我认为我尝试遍历 JSON 文件中的数组的方式有问题?
export class HomePage {
@ViewChild('myswing1') swingStack: SwingStackComponent;
@ViewChildren('mycards1') swingCards: QueryList<SwingCardComponent>;
cards: Array<any>;
stackConfig: StackConfig;
recentCard: string = '';
constructor(public http: Http) {
this.stackConfig = {
throwOutConfidence: (offsetX, offsetY, element) => {
return Math.min(Math.abs(offsetX)/(element.offsetWidth/2),1);
},
transform: (element, x, y, r) => {
this.onItemMove(element, x, y, r);
},
throwOutDistance: (d) => {
return 800;
}
};
}
ngAfterViewInit(){
this.swingStack.throwin.subscribe((event: DragEvent) => {
event.target.style.background = '#ffffff';
});
this.cards = [{email: ''}];
this.addNewCards(1);
}
voteUp(like: boolean) {
let removedCard = this.cards.pop();
this.addNewCards(1);
if (like){
this.recentCard = 'You liked: ' + removedCard.email;
} else{
this.recentCard = 'You disliked: ' + removedCard.email;
}
}
addNewCards(count: number){
this.http.get('../../assets/data/pics.json').map(data => data.json().results).subscribe(result => {
for (let val of result){
for (var count = count; count<pic.length; count++){
this.cards.push(val);
}
}
})
}
我也尝试为对象制作单独的 JSON 文件并以这种方式检索它,但也失败了。我尝试控制台记录 JSON 数据以查看它检索的内容,但始终只是第二个对象。之后,堆栈中不会出现任何卡。
我所做的两种方法的输出都只是一张卡片,刷卡后会出现一个"未定义"的字符串。
顺便说一下,我是使用Ionic和Typescript的新手(而且我有点匆忙(,所以任何帮助或建议将不胜感激!
(这也是我的 JSON 文件的样子,如果它有帮助的话:(
{
"pics": [
{
"name": "balls",
"pic": "assets/img/pics/01.jpg"
},
{
"name": "snowy field",
"pic": "assets/img/pics/02.jpg"
},
{
"name": "hotel bedroom",
"pic": "assets/img/pics/03.png"
},
{
"name": "apartments",
"pic": "assets/img/pics/04.jpg"
}
]
}
在对一段代码进行所需的更改之前,您应该确保了解一段代码的实际操作。
以下是用于添加新卡的代码:
addNewCards(count: number){
this.http.get('https://randomuser.me/api/?results=' + count).map(data => data.json().results).subscribe(result => {
for (let val of result){
for (var count = count; count<pic.length; count++){
this.cards.push(val);
}
}
})
}
查看此代码,有几点很突出,我们将分解为几个步骤:
- 如果要读取自己的 JSON 文件,为什么要向 randomuser.me API 发出请求(
this.http.get('https://randomuser.me/api/?results' + count)
?在这里,您应该输入您自己的 JSON 文件的路径 (this.http.get('../../assets/data/pics.json')
. - 接下来,看看代码如何处理结果(
.map(data => data.json().results)
(。如果我们看一下从 API 返回的 JSON(https://randomuser.me/api/?results=1(,我们会发现实际结果在响应的"结果"部分,所以.map(data => data.json().results)
实际上是在说:获取返回的内容,将其转换为 JSON,然后给我结果。由于您的 JSON 文件没有这样的"结果"部分,因此请求文件的该部分是没有意义的。您可以将其更改为.map(data => data.json().pics)
以获取所有图片的列表。 - 现在我假设你想添加"计数"新卡,所以如果计数是 3,你想添加 3 张新卡。首先请注意,这适用于 API,因为它可以创建无限的结果,但如果您想从自己的 JSON 中添加 10 张卡片,则必须确保 JSON 中实际上至少有 10 个条目。
让我们一步一步地看一下函数的实际主体:
for (let val of result){
遍历请求返回的每个条目,所以对你来说,它会遍历所有图片。在这个循环中,你正在创建一个新的循环,它本身有几个不同的问题(var "count" 与参数 "count" 同名,"pic" 没有在任何地方定义(,但即使循环是正确的,你仍然循环遍历所有结果,所以你没有过滤掉大量的结果。如果您确保图片列表的长度至少与计数相同,则可以执行更多类似操作:for (let i = 0; i < count; i++) { this.cards.push(result[i[); }
所以最后会给我们留下:
addNewCards(count: number) {
this.http.get('../../assets/data/pics.json')
.map(data => data.json().pics)
.subscribe(result => {
for (let i = 0; i < count; i++) {
this.cards.push(result[i]);
}
})
}
祝你好运,这里的主要教训是:在尝试更改之前了解您正在使用的代码。
看看我的ionic-soundboard项目,看看我如何使用自己的JSON文件来填充条目列表。
除了上面 Rosco 修复了我的循环的答案之外,Disqus 用户 JB 提供了一个很好的解决方案,使 JSON 文件中的每个对象都出现在每张卡片上。 HTML 文件中的 card-stackdiv 和 ion-card 应该像这样附加(最后修改了zIndex 和 marginTop 属性(:
<div swing-stack #myswing1 [stackConfig]="stackConfig" (throwoutleft)="voteUp(true)" (throwoutright)="voteUp(false)" id="card-stack" [style.zIndex]="-1000">
<ion-card #mycards1 swing-card *ngFor="let c of cards; trackBy:trackByCards; let i=index;" [style.zIndex]="-1 * i" [style.marginTop]="i === 0 ? '0px' : '12px'">
对于 Typescript 文件,在 voteUp(( 函数中:
let removedCard = this.cards.shift();
区别在于使用shift(((而不是pop(((,因为这会从 JSON 文件中的数组中删除第一个元素。仅此而已。谢谢罗斯科和新山!!
注意:一旦你遍历了数组中的所有元素,它就会再次返回到第一个元素;这是一个无限的卡片循环。