如何遍历单个 JSON 文件以使每个对象出现在 Ionic 火种卡上?
Posted
技术标签:
【中文标题】如何遍历单个 JSON 文件以使每个对象出现在 Ionic 火种卡上?【英文标题】:How do I loop through a single JSON file for each object to appear on Ionic tinder cards? 【发布时间】:2018-01-21 09:41:24 【问题描述】:所以我正在关注this tutorial 如何为 Ionic 2 构建火种卡。本教程使用 randomuser.me 的 API,但我想使用我自己的 JSON 文件。
下面是我的打字稿文件(虽然我省略了一些不相关的sn-ps代码),最底层的函数是我为了尝试检索我自己的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 文件并检索它this way,但也失败了。我尝试控制台记录 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"
]
【问题讨论】:
【参考方案1】:在对代码进行必要的更改之前,您应该确保了解一段代码的实际作用。
这是您用于添加新卡的代码:
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 (https://randomuser.me/api/?results=1) 返回的 JSON,我们会看到实际结果在响应的“结果”部分中,因此 .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 project,看看我如何使用我自己的 JSON 文件来填充条目列表。
【讨论】:
感谢您的详尽解释,我的 JSON 文件中的数据现在出现在卡片上!但是,它仍然存在问题。我刷的每张卡都只显示同一个对象。你认为我必须彻底更改代码以使每个对象都出现在我可以刷的每张卡片上吗? 好吧,当你用 addNewCards(1) 添加一张卡片时,你总是添加列表中的第一张卡片。如果您希望发生其他事情,则必须更改循环。例如,如果您想从 JSON 文件中添加一个随机条目,您可以将this.cards.push(result[i]);
更改为 this.cards.push(result[Math.floor(Math.random() * result.length)];
【参考方案2】:
除了上面修复我的循环的 Rosco 回答之外,Disqus user JB 还提供了一个很好的解决方案,可以让 JSON 文件中的每个对象出现在每张卡片上。 html 文件中的 card-stack div 和 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()),因为这会从数组中删除 first 元素JSON 文件。就是这样。谢谢 Rosco 和 JB!
注意:一旦你遍历了数组中的所有元素,它就会再次返回到第一个元素;这是一个无限循环的卡片
【讨论】:
以上是关于如何遍历单个 JSON 文件以使每个对象出现在 Ionic 火种卡上?的主要内容,如果未能解决你的问题,请参考以下文章