In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "bytom how to display the details of the transaction", the content of the article is simple and clear, easy to learn and understand, the following please follow the editor's ideas slowly in depth, together to study and learn "bytom how to display the details of the transaction"!
First look at the corresponding picture:
Because the picture is too long, it is divided into two, which can actually be regarded as one.
So how did this page come from? After displaying the transaction summary information in the form of a list, you can click the "View details" link in the upper right corner of the summary information to open it.
Let's take a look at how Bei Yuan displays the details of this transaction in this article.
Since it is divided into front and rear, we will, as before, divide it into two small problems:
How does the front end send the request to the background and display the data
How does the back end get the corresponding data and send it to the foreground?
It is important to note that this table contains a lot of information, but we are not going to explain it in this article. Because what can be understood can be understood at a glance, and what is not understood needs to be accurately understood than the original core before it can be explained clearly, and this part will be studied later.
How does the front end send the request to the background and display the data
First, let's take a look at the routing path that displays the transaction details page. When we mouse over "View details" in the upper-right corner of the deal summary page, we will find that url is similar to:
Http://localhost:9888/dashboard/transactions/2d94709749dc59f69cad4d6aea666586d9f7e86b96c9ee81d06f66d4afb5d6dd
Http://localhost:9888/dashboard/ can be seen as the root path of this application, so the routing path should be / transactions/2d94709749dc59f69cad4d6aea666586d9f7e86b96c9ee81d06f66d4afb5d6dd, and the one that is so long is obviously an id, so we should look for a string like / transactions/:id in the code. Oh, unfortunately we can't find it.
We can only start from scratch, first find the definition of the front-end route:
Src/routes.js#L15-L35
/ /. Import {routes as transactions} from 'features/transactions'//. Const makeRoutes = (store) = > ({path:' /', component: Container, childRoutes: [/ /. Transactions (store), / /...]})
The transactions is what we need, and it corresponds to features/transactions/routes.js:
Src/features/transactions/routes.js#L1-L21
Import {List, New, AssetShow, AssetUpdate} from'. / components'import {makeRoutes} from 'features/shared'export default (store) = > {return makeRoutes (store,' transaction', List, New, Show, / /...)}
This function will generate many related routing paths for transactions. When we upload some components, such as list display List, new New, display details Show, etc., makeRoutes will add the relevant path according to the pre-defined path rules. Let's take a look at makeRoutes:
Src/features/shared/routes.js#L1-L44
Import {RoutingContainer} from 'features/shared/components'import {humanize} from' utility/string'import actions from 'actions'const makeRoutes = (store, type, List, New, Show, options = {}) = > {const loadPage = () = > {store.dispatch (action [type] .fetchAll ())} const childRoutes = [] if (New) {childRoutes.push ({path:' create') Component: New})} if (options.childRoutes) {childRoutes.push (... options.childRoutes)} / / 1. If (Show) {childRoutes.push ({path:': id', component: Show})} return {/ / 2. Path: options.path | | type +'s clients, component: RoutingContainer, name: options.name | | humanize (type +') Name_zh: options.name_zh, indexRoute: {component: List, onEnter: (nextState, replace) = > {loadPage (nextState, replace)}, onChange: (_, nextState, replace) = > {loadPage (nextState, replace)}, childRoutes: childRoutes}}
This code looks familiar because we've seen it before when we looked at the list of balances and transactions. Today we are focusing on Show, the code marked first.
As you can see, when the Show component is passed in, you need to generate the relevant routing path for it. Specifically, add a path to the childRouters as: id, and its own routing path is defined in the second place, which defaults to type + 's routing. In this case, the value of type is transaction, so the complete path corresponding to Show is / transactions/:id, which is exactly what we need.
Going back to the first code, you can see that the Show component is passed in from the outside, and you can see from the previous function that it corresponds to src/features/transactions/components/Show.jsx.
Let's go in and take a look at the Show.jsx. The first thing is to define the function render of the html component:
Src/features/transactions/components/Show.jsx#L16-L96
Class Show extends BaseShow {render () {/ / 1. Const item = this.props.item const lang = this.props.lang const btmAmountUnit = this.props.btmAmountUnit let view if (item) {/ /.. View = / /... {item.inputs.map ((input, index) = >)} {item.outputs.map ((output, index) = >)}} return this.renderIfFound (view)}}
The code has been greatly simplified by me, mainly omitting a lot of data calculations and some parameters of the display component. I divided the code into two parts:
The first thing to pay attention to is the code like const item = this.props.item, where item is the data we want to show, and the corresponding article is a transaction object, which is obtained from this.props, so we can infer that in this file (or a referenced file), there will be a connect method to plug the data in store. We'll check it out later. Let's not say the last two lines are similar.
The second part of the code is mainly the definition of the page view, you can see that it is mainly used in another custom component KeyValueTable. We will not follow the code, with reference to the previous page effect, we can imagine that it is in the form of a table to display some key-value data.
So let's continue to look for connect and soon find the following definition at the back of the same page:
Src/features/transactions/components/Show.jsx#L100-L117
Import {actions} from 'features/transactions'import {connect} from' react-redux'const mapStateToProps = (state, ownProps) = > ({item: state.transaction.items [ownProps.params.id], lang: state.core.lang, btmAmountUnit: state.core.btmAmountUnit, highestBlock: state.core.coreData & & state.core.coreData.highestBlock}) / /. Export default connect (mapStateToProps, / /) (Show)
I left only the mapStateToProps that needs to be followed. As you can see, the assignments of several variables we saw in the previous section 1 are all defined here, of which the most important item is taken from items in transaction in store's current state state.
So what is state.transaction? At first, I thought it was some data we got back from the background. I put it in store using the name transaction, but I couldn't find it, but finally I found out it wasn't.
The reality is that where we define reducer, there is a makeRootReducer:
Src/reducers.js#L1-L62
/ /. Import {reducers as transaction} from 'features/transactions'//... const makeRootReducer = () = > (state, action) = > {/ /. Return combineReducers ({/ /... Transaction, / /...}) (state, action)}
It turns out that it was built here. First of all, {transaction} the syntax of ES6 is changed to the usual way of writing, which is:
{transaction: transaction}
In addition, the combineReducers method is used to merge multiple reducer (probably because the store is too large, so split it into multiple reducer management, each reducer only needs to deal with the part it is interested in), and after the merger, the store will look something like this:
{"transaction": {.}, / /.}
So the previous state.transaction refers to the {.} here.
So go on, in the previous code, you can see from state.transaction.items [ownProps.params.id] that state.transaction also has a property of items, which holds a transaction array retrieved from the background / list-transactions. When was it added?
This question baffled me. I spent hours searching through Bihara's front and rear warehouse, but couldn't find it. I finally had to use Chrome's Redux DevTools method and found that items existed from the very beginning:
There are two red boxes on the picture, the left shows that I am now choosing the initial state, and the right shows that transaction already has items at the beginning, so I suddenly realized that this is not the same as before. So the definition was quickly found:
Src/features/transactions/reducers.js#L7-L16
Export default combineReducers ({items: reducers.itemsReducer (type), queries: reducers.queriesReducer (type), generated: (state = [], action) = > {if (action.type = = 'GENERATED_TX_HEX') {return [action.generated,... state] .slice (0, maxGeneratedHistory)} return state},})
Sure enough, here is also a combination of several reducer using combineReducers, so there will be several key here in store, including items, as well as queries and generated that we don't care about.
It took me all afternoon to finally figure out this piece. It seems that for the analysis of dynamic language, the thinking must be greatly inspired, can not presuppose the reason, in addition, we should use a variety of debugging tools to view the data from different angles. If it wasn't for Redux's Chrome plug-in, I don't know how long it would be stuck.
Personally, I prefer statically typed languages. For JavaScript, unless you can't avoid it, the main reason is that there are too few clues to refer to each other in the code, and most of the time you have to read the document, code or even guess, unable to take advantage of the jump function provided by the editor.
After knowing the origin of state.transaction.items, the rest is easy to say. We got the transaction we need from state.transaction.items [ownProps.params.id], so when did we put the data in state.transaction.items?
Let's go back to the previous makeRoutes:
Src/features/shared/routes.js#L1-L44
/ /... import actions from 'actions'const makeRoutes = (store, type, List, New, Show, options = {}) = > {/ / 2. Const loadPage = () = > {store.dispatch (action [type] .fetchAll ())} / /. Return {path: options.path | | type + RoutingContainer, name: options.name | | humanize (type +'), name_zh: options.name_zh, indexRoute: {component: List, onEnter: (nextState, replace) = > {loadPage (nextState, replace)}, / / 1. OnChange: (_, nextState, replace) = > {loadPage (nextState, replace)}} ChildRoutes: childRoutes}}
In the first place above, for indexRoute, there is a trigger for onChange. What it means is that when the path of the route changes and the new path belongs to the path (or child path) of the current index route, the later function will trigger. The loadPage in the later function is defined in the second code, which in turn dispatch the action generated by Actions.fetchAll (). Because type is a transaction in this article, by tracking it step by step (a little troublesome here, but we've gone through it in the previous article), we find that actions.fetchAll corresponds to src/features/shared/actions/list.js:
Src/features/shared/actions/list.js#L4-L147
Export default function (type, options = {}) {const listPath = options.listPath | | `/ ${type} s` const clientApi = () = > options.clientApi? Options.clientApi (): chainClient () [`$ {type} s`] / /. Const fetchAll = () = > {/ /.} / /. Return {/ /... FetchAll, / /...}}
If we still remember this piece of code, we will know that it will eventually visit the / list-transactions in the background and call dispatch ("RECEIVED_TRANSACTION_ITEMS") after getting the data, and it will be handled by the following reducer:
Src/features/shared/reducers.js#L6-L28
Export const itemsReducer = (type, idFunc = defaultIdFunc) = > (state = {}, action) = > {if (action.type = = `ITEMS`) {/ / 1. Const newObjects = {} / / 2. Const data = type.toUpperCase ()! = 'TRANSACTION'? Action.param.data: action.param.data.map (data = > ({... data, id: data.txId, timestamp: data.blockTime, blockId: data.blockHash, position: data.blockIndex})) / / 3. (data | | []) .forEach (item = > {if (! item.id) {item.id = idFunc (item)} newobjects [idFunc (item)] = item}) return newObjects} / /. Return state}
Explain the three codes in this function in turn:
In the first place, a new empty object, newObjects, is created, which will replace state.transaction.items at last, and then assign a value to it.
The second is to do some processing on the incoming data. If type is transaction, it will promote some attributes in each element of the array to the root, making it easy to use.
The third is to put each element into the newObjects. The id is key and the object itself is value.
After these processes, we can use state.transaction.items [ownProps.params.id] to get the appropriate transaction object and display it by Show.jsx.
The front part is basically clear. Let's move on to the back end.
How does the back end get the corresponding data and send it to the foreground?
As we said earlier, based on past experience, we can deduce that the front end will access the back-end / list-transactions interface. We are pleased to find that we have studied this interface in the previous article, so we can skip it completely.
Thank you for your reading, the above is the content of "bytom how to display transaction details". After the study of this article, I believe you have a deeper understanding of how bytom displays transaction details, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.