上节内容中我们讲了前端和智能合约之间通过一个service组件进行交互,并将前端的数据通过push action的方式存储到多索引表中。那么我们如何从智能合约的表中取数据出来并展示在前端界面呢,这便是我们今天要学习的内容。
对eos有一定了解的朋友们应该知道RPC接口的存在,我们可以通过cleos命令行的get table来获取表中的内容,也可以通过RPC接口中的get_table_rows来获取相关内容然后展示在前端页面上,其主要流程可以按照下图展示,我们接下来就来看这些操作是如何实现的:
在上一节内容中我们引入了ApiService的概念,接下来让我们在ApiService中添加一个获取当前用户信息的接口getUserByName(),username将是这个函数的唯一参数,当然通过上面的介绍我们很容易联想到RPC接口中的get_table_rows,我们具体来看代码:
1static async getUserByName(username) {
2 try {
3 //新建一个RPC对象
4 const rpc = new Rpc.JsonRpc(process.env.REACT_APP_EOS_HTTP_ENDPOINT);
5 const result = await rpc.get_table_rows({
6 //传参格式为JSON
7 "json": true,
8 "code": prodcess.env.REACT_APP_EOS_CONTRACT_NAME,
9 //code为合约账户名
10 "scope": process.env.REACT_APP_EOS_CONTRACT_NAME,
11 // 合约的scope
12 "table": "users",
13 // 要查询的表明
14 "limit": 1,
15 // 只查一个
16 "lower_bound": username,
17 //这个lower_bound和upper_bound建议参考以下multi-index.hpp学习哦
18 });
19 return result.rows[0];
20 } catch (err) {
21 console.error(err);
22 }
23 }
在上面的例子中我们使用了limit,lower_bound等限制,关于multi-index的内容,还是建议各位读者稍微阅读下源码,即multi-index.hpp中的一些内容,这样能更方便的理解多索引表,当然我以前的文章中也多次提及过:
eos源码赏析(十三):EOS智能合约数据持久化存储(上)
eos源码赏析(十四):EOS智能合约数据持久化存储(下)
eos源码赏析(十六):EOS智能合约数据表查询
getUserByName的返回结果将是一个JSON格式的字符串,包含了玩家的信息以及游戏的相关信息。
然后我们来创建一个PlayerProfile组件来展示上面接口返回的内容,PlayerProfile是React中一个用于展示内容的组件,在这里我们需要把他包含到Game组件内,做完以上内容我们可以发现:
mapStateToProps 和mapDispatchToProps已经被添加,用来链接组件和Redux store:
1import { connect } from 'react-redux';
2// Game subcomponents
3import { PlayerProfile } from './components';
constructor在Game组件启动之前获取多索引表中的数据:
1 constructor(props) {
2 // 初始化构造函数
3 super(props);
4 // 绑定
5 this.loadUser = this.loadUser.bind(this);
6 this.loadUser();
7 }
loaduser,通过ApiService里的getUserByName获取最新的玩家的数据:
1 loadUser() {
2 const { setUser, user: { name } } = this.props;
3 // 通过ApiService发送请求,调用getUserByName然后在通过RPC接口中的get_table_rows来查询表中的数据,并解析展示出来
4 return ApiService.getUserByName(name).then(user => {
5 setUser({
6 win_count: user.win_count,
7 lost_count: user.lost_count,
8 game: user.game_data,
9 });
10 });
11 }
当PlayerProfile创建完成之后,我们在登录之后会看到已登录用户的信息,比如玩家名,赢的次数,输的次数等。但是有个问题需要注意,用户数据存储在了Redux store中,但是Redux store会在每次浏览器页面刷新之后进行重构,数据就会被清空,我们怎么来解决呢?
我们可以在ApiService中添加一个getCurrentUser函数从本地存储中来获取当前用户的信息,获取到之后可以调用智能合约的login action,如果登录成功了,我们就再次把用户数据存储到redux store中,从而实现自动登录的功能:
1 static getCurrentUser() {
2 return new Promise((resolve, reject) => {
3 if (!localStorage.getItem("cardgame_account")) {
4 return reject();
5 }
6 takeAction("login", { username: localStorage.getItem("cardgame_account") })
7 .then(() => {
8 resolve(localStorage.getItem("cardgame_account"));
9 })
10 .catch(err => {
11 localStorage.removeItem("cardgame_account");
12 localStorage.removeItem("cardgame_key");
13 reject(err);
14 });
15 });
16 }
登录成功的页面如下所示:
如果你觉得我的文章对你有一定的帮助,请点击文章末尾的喜欢该作者。
如果你对eos开发感兴趣,欢迎关注本公众号,一起学习eos开发。
微信公众号
有任何疑问或者指教请添加本人个人微信,当然有对eos开发感兴趣或者金庸粉的也可以添加一起交流,备注eos开发或金庸。
个人微信号