所以我在React上有这个代码,我试图让一个glyphicon随着排序方向的变化而变化。
我设法从null
到asc
到desc
获取方向标记,然后使用columnClicked
null
作为this.state obj的一部分:
sortDirection: {
url: null,
size: null,
time: null
}
然后我有一些已经绑定的函数。
onColumnSort(dataKey, dir) {
this.setState({sortKey: dataKey, sortDirection: dir})
}
columnClicked(dataKey){
let sortDirections = this.state.sortDirection,
dir = sortDirections[dataKey]
if (dir === null) {dir = 'asc'}
else if (dir === 'asc') { dir = 'desc'}
else if (dir === 'desc') { dir = null }
// Reset sort
_.each(_.keys(sortDirections), function(x) {
sortDirections[x] = null
})
sortDirections[dataKey] = dir
if (this.props.onColumnSort) {
this.props.onColumnSort(dataKey, dir)
}
}
RenderHeader(label, dataKey) {
let dir = this.state.sortDirection[dataKey],
classMap = {
asc: 'glyphicon glyphicon-sort-by-attributes',
desc: 'glyphicon glyphicon-sort-by-attributes-alt',
}
console.log(classMap[dir]) // prints undefined
let sortClass = dir ? classMap[dir] : 'See me?'
console.log(dir) // prints null
console.log(sortClass) // prints the string set See me?
return (
<div className="text-primary sortable"
onClick={() => this.columnClicked(dataKey)}>
<strong>{label}</strong>
<i className={sortClass}></i>
</div>
)
}
问题是renderHeadrer没有获取更改,并且总是导致classMap[null
]不打印字形而不是classMap[asc]
,classMap[desc]
然后classMap[null]
,所以我可以告诉字形classMap对象根本没有被使用,因为func
实际上没有选择标志。但我不明白错误。
我一直在努力让这项工作持续数小时而且不能似乎做对了。 任何指针都会很棒,非常有帮助。欢呼声。
组件1进入组件2
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
import 'fixed-data-table/dist/fixed-data-table.css'
// import FixedDataTable from 'fixed-data-table-2'
import FixedDataTable from 'fixed-data-table'
import {Grid, Row, Col, PageHeader, Button, ButtonGroup,
FormGroup, FormControl, Glyphicon} from 'react-bootstrap'
import _ from 'lodash'
import PropTypes from 'prop-types'
'use strict'
const {Table, Column, Cell, rowIndex,
columnKey, data, field} = FixedDataTable
const GutterWidth = 30
export default class HarEntryTable extends Component {
constructor() {
super()
this.state = {
isColumnResizing: false,
columnWidths: {
url:500,
size:200,
time:200
},
sortDirection: {
url: null,
size: null,
time: null
},
tableWidth:1000,
tableHeight: 500
}
this._onColumnResized = this._onColumnResized.bind(this)
this._onResize = this._onResize.bind(this)
this._getEntry = this._getEntry.bind(this)
this._readKey = this._readKey.bind(this)
this._columnClicked = this._columnClicked.bind(this)
this._RenderHeader = this._RenderHeader.bind(this)
}
_readKey(key, entry) {
let keyMap = {
url: 'request.url',
time: 'time.start'
}
//size is not inside keyMap so it's key is passed instead
key = keyMap[key] || key
return _.get(entry, key)
}
_getEntry(index) {
return this.props.entries[index]
}
_onResize() {
// automatically adjustment of width and height of table
// let parent = ReactDOM.findDOMNode(this).parentNode
let parent = ReactDOM.findDOMNode(this.refs.entriesTable).parentNode
this.setState({
tableWidth: parent.clientWidth - GutterWidth,
tableHeight: document.body.clientHeight -
parent.offsetTop - GutterWidth * 0.5
})
}
componentDidMount() {
let global = window
// you debounce something that repeats a lot
global.addEventListener('resize',
_.debounce(this._onResize), 50, {leading : true, trailing: true})
this._onResize()
}
_onColumnResized(newColumnWidth, columnKey) {
let columnWidths = this.state.columnWidths
// Select the col by key, then the new col
// width can be set anything, this case
// is called newColumnWidth... could be x
columnWidths[columnKey] = newColumnWidth
this.setState({columnWidths: columnWidths, isResizable:false})
}
_columnClicked(dataKey) {
let sortDirections = this.state.sortDirection,
dir = sortDirections[dataKey]
if (dir === null) {dir = 'asc'}
else if (dir === 'asc') { dir = 'desc'}
else if (dir === 'desc') { dir = null }
// Reset sort
_.each(_.keys(sortDirections), function(x) {
sortDirections[x] = null
})
sortDirections[dataKey] = dir
if (this.props.onColumnSort) {
this.props.onColumnSort(dataKey, dir)
}
}
_RenderHeader(label, dataKey) {
let dir = this.state.sortDirection[dataKey],
classMap = {
asc: 'glyphicon glyphicon-sort-by-attributes',
desc: 'glyphicon glyphicon-sort-by-attributes-alt',
}
// console.log(classMap[dir])
let sortClass = dir ? classMap[dir] : 'See me?'
// console.log(dir)
// console.log(sortClass)
// let sortClass = 'glyphicon glyphicon-sort'
return (
<div className="text-primary sortable"
onClick={() => this._columnClicked(dataKey)}>
<strong>{label}</strong>
<i className={sortClass}></i>
</div>
)
}
render() {
return (
<Table ref="entriesTable"
rowsCount={this.props.entries.length}
width={this.state.tableWidth}
headerHeight={35}
height={this.state.tableHeight}
rowHeight={30}
rowGetter={this._getEntry}
isColumnResizing={this.state.isColumnResizing}
onColumnResizeEndCallback={this._onColumnResized}
>
<Column header={<Cell>Url</Cell>}
headerRenderer={this._RenderHeader}
label='Url'
columnKey='url'
dataKey="url"
cellDataGetter={this._readKey}
width={this.state.columnWidths.url}
isResizable={true}
flexGrow={null} />
<Column header={<Cell>Size</Cell>}
headerRenderer={this._RenderHeader}
label='Size'
columnKey="size"
dataKey="size"
width={this.state.columnWidths.size}
cellDataGetter={this._readKey}
isResizable={true} />
<Column header={<Cell>TimeLine</Cell>}
headerRenderer={this._RenderHeader}
label='TimeLine'
columnKey="time"
dataKey="time"
width={this.state.columnWidths.time}
cellDataGetter={this._readKey}
minWidth={200}
isResizable={true} />
</Table>
)
}
}
HarEntryTable.defaultProps = {
entries: [],
page: null,
onColumnSort: null
}
HarEntryTable.porpType = {
entries: PropTypes.array,
onColumnSort: PropTypes.func,
page: PropTypes.object
}
import ReactDOM from 'react-dom'
import React, {Component, PorpTypes} from 'react'
import _ from 'lodash'
import mimeTypes from '../Core/mimeTypes.js'
import {Grid, Row, Col, PageHeader, Button, ButtonGroup,
FormGroup, FormControl, Alert} from 'react-bootstrap'
import HarEntryTable from './HarEntryTable.jsx'
import harParser from '../Core/harParser.js'
'use strict'
export default class HarViewer extends Component {
constructor() {
super()
this.state = this._initialState()
this._sampleChanged = this._sampleChanged.bind(this)
this._filterdTextChanged = this._filterdTextChanged.bind(this)
this._filterRequested = this._filterRequested.bind(this)
this._renderHeader = this._renderHeader.bind(this)
this._initialState = this._initialState.bind(this)
this._renderViewer = this._renderViewer.bind(this)
this._renderEmptyViewer = this._renderEmptyViewer.bind(this)
this._onColumnSort = this._onColumnSort.bind(this)
}
// ___________________
// METHODS TO USE |
// ___________________|
_initialState() {
return {
activeHar: null,
sortKey: null,
sortDirection: null
}
}
_sampleChanged() {
let selection = ReactDOM.findDOMNode(this.refs.selector).value
let har = selection
? _.find(window.samples, s => s.id === selection).har
: null
if(har) {
this.setState({activeHar: har})
}
else {
this.setState(this._initialState())
}
}
_filterRequested(type, event) {}
_filterdTextChanged() {}
_onColumnSort(dataKey, dir) {
// this.setState({sortKey: dataKey, sortDirection: dir})
const nextSortkey = Object.assign({}, this.state.sortKey, dataKey)
const sortDirection = Object.assign({}, this.state.sortDirection, dir)
this.setState({sortKey: nextSortkey, sortDirection: sortDirection})
}
_sortEntriesByKey(sortKey, sortDirection, entries) {
if(_.isEmpty(sortKey) | _.isEmpty(sortDirection)) return entries
let keyMap = {
url: 'request.url',
time: 'time.start'
},
getValue = function(entry) {
let key = keyMap[sortKey] || sortKey
return _.get(entry, key)
}
let sorted = _.sortBy(entries, getValue)
if (sortDirection === 'desc') {
sorted.reverse()
}
return sorted
}
_createButton(type, label) {
var handler = this._filterRequested(type)
return (
<Button key={type}
bsStyle="primary"
active={this.state.type === type}
onClick={handler}> { label }
</Button>
)
}
render() {
let content = this.state.activeHar
? this._renderViewer(this.state.activeHar)
: this._renderEmptyViewer()
return (
<div>
{this._renderHeader()}
{content}
</div>
)
}
_renderEmptyViewer() {
return(
<Grid>
<Row>
<Col sm={12}>
<p></p>
<Alert bsStyle="warning">
<strong>No HAR loaded</strong>
</Alert>
</Col>
</Row>
</Grid>
)
}
_renderViewer(har) {
let pages = harParser.parse(har),
currentPage = pages[0]
let entries = this._sortEntriesByKey(this.state.sortKey,
this.state.sortDirection,
currentPage.entries)
return (
<Grid>
<Row>
<Col sm={12}>
<HarEntryTable entries={entries}
onColumnSort={this._onColumnSort}/>
</Col>
</Row>
</Grid>
)
}
// renderHeader is returning the Grid
_renderHeader() {
const buttons = _.map(_.keys(mimeTypes.types), (x) => {
return this._createButton(x, mimeTypes.types[x].label)
})
//populate the select component
const options = _.map(window.samples, (s) => {
return ( <option key={s.id} value={s.id} > {s.label} </option> )
})
return (
<Grid>
<Row>
<Col className="pageHeader" sm={12}>
<PageHeader>HarViewer</PageHeader>
</Col>
</Row>
<Row>
<Col sm={12}>
<p>PIE CHART</p>
</Col>
</Row>
<Row>
<Col className="margined" sm={4}>
<div>
<label className="control-label"></label>
<select ref="selector" className="form-control"
onChange={this._sampleChanged}>
<option value="">-----</option>
{options}
</select>
</div>
</Col>
</Row>
<Row>
<Col sm={8}>
<ButtonGroup bsSize="large">
{this._createButton('all', 'All')}
{buttons}
</ButtonGroup>
</Col>
<Col sm={4}>
<FormGroup>
<FormControl type="search"
placeholder="Search URL"
bsSize="small"
onChange={this._filterdTextChanged}
inputRef={ ref => { this.input = ref } } />
</FormGroup>
</Col>
</Row>
</Grid>
)
}
}
HarViewer.defaultProps = {
entries: []
}
抱歉长度......