2017-10-06 166 views
0

我们将实现一个columnpicker,目前我唯一的想法是实现包装列表的ColumnPickableList。这也会包含一个复选框列表,使用户可以隐藏一列。有没有简单的方法来实现List列选取器?

但在此之前我继续做,我只是想知道,如果我reinveting方向盘,如果有解决这个更简单的方法?

回答

2

没有简单的方法。你必须实现自己的List组件为

0

我在这下面了,因为我努力使这项工作。也许这是因为我选择创建一个包装器来过滤要显示的孩子。所以在技术上这种方法不会实现自己的列表。

我已经我希望将工作天真的草案,但未能重新渲染孩子,即使他们改变/在父组件过滤。

在ColumnPickableList的执行console.log(..)渲染() - 函数不会打印正确的儿童/道具,但还是孩子们将不会更新/重新渲染。任何线索为什么?这种方法太天真了吗?

因此,这里是目前的草案:

ColumnPicker.js

import React, { PropTypes } from 'react'; 

import Checkbox from 'material-ui/Checkbox'; 

export default class ColumnPicker extends React.Component { 

    constructor(props) { 
    super(props); 
    this.onCheck = this.onCheck.bind(this); 
    } 

    onCheck(column, isChecked) { 
    return this.props.onCheckboxChanged(column, isChecked); 
    } 

    renderCheckbox(column, onCheck) { 
    const disabled = (column.source === 'id'); 
    return (<Checkbox key={column.source} label={column.source.toUpperCase()} onCheck={(event, checked) => onCheck(column, checked)} defaultChecked disabled={disabled} />); 
    } 

    render() { 
    const columns = this.props.columns || []; 

    return (
     <div className="column-picker"> 
     {columns.map((column) => { 
      return this.renderCheckbox(column, this.onCheck); 
     })} 
     </div> 
    ); 
    } 
} 

ColumnPicker.propTypes = { 
    columns: PropTypes.array, 
    onCheckboxChanged: PropTypes.func, 
}; 

ColumnPicker.defaultProps = { 
    columns: [], // [{source: myField, checked: true} ...] 
}; 

ColumnPickableList.js:

import React, { PropTypes } from 'react'; 
import { connect } from 'react-redux'; 
import { List, Datagrid } from 'admin-on-rest'; 
import ColumnPicker from './ColumnPicker'; 

import { toggleColumnPickerStatusAction, initializeColumnPickerAction } from './actions'; 

export class ColumnPickableList extends React.Component { 

    componentWillMount() { 
    let columnSourceNames = []; 
    if (this.props.children) { 
     columnSourceNames = React.Children.map(this.props.children, (child) => { 
     return ({ source: child.props.source, checked: true }); 
     }); 
    } 
    const columnsDisplayed = columnSourceNames.filter((column) => column.source); 
    this.props.initializeColumnPicker(this.props.resource, columnsDisplayed); 
    } 

    shouldComponentUpdate(nextProps) { 
    const diff = nextProps.columnsDisplayed.filter((currentColumn) => { 
     return !this.props.columnsDisplayed.some((prevColumn) => { 
     return currentColumn.source === prevColumn.source && currentColumn.checked === prevColumn.checked; 
     }); 
    }); 

    return diff.length > 0; 
    } 

    removeHiddenColumns(children) { 
    return React.Children.map(children, (child) => { 
     if (!child.props.source) { 
     return child; 
     } 
     const column = this.props.columnsDisplayed.find((columnDisplayed) => { 
     return columnDisplayed.source === child.props.source; 
     }); 

     if (this.props.columnsDisplayed.length === 0 || (column && column.checked)) { 
     return React.cloneElement(child); 
     } 
     return null; 
    }); 
    } 

    render() { 
    const { children, ...rest } = this.props; 
    const displayedChildren = this.removeHiddenColumns(children); 
    console.log('Does it render? Rendering children', displayedChildren.map((child) => child.props.source)); 

    return (
     <div className="columnpickable-list"> 
     <ColumnPicker columns={this.props.columnsDisplayed} onCheckboxChanged={this.props.handleCheckboxChanged} /> 
     <List {...rest}> 
      <Datagrid> 
      {displayedChildren} 
      </Datagrid> 
     </List> 
     </div> 
    ); 
    } 
} 

ColumnPickableList.propTypes = { 
    resource: PropTypes.string, 
    columnsDisplayed: PropTypes.array, 
    children: PropTypes.node, 
    initializeColumnPicker: PropTypes.func, 
    handleCheckboxChanged: PropTypes.func, 
}; 

ColumnPickableList.defaultProps = { 
    columnsDisplayed: [], 
}; 


function mapStateToProps(state) { 
    return { 
    columnsDisplayed: state.columnsDisplayed || [], 
    }; 
} 

actions.js:

export const actions = { 
    INIT_COLUMNPICKER: 'INIT_COLUMNPICKER', 
    TOGGLE_COLUMNPICKER_STATUS: 'UPDATE_COLUMNPICKER_STATUS', 
    UPDATE_COLUMNPICKER_STATUSES: 'UPDATE_COLUMNPICKER_STATUSES', 
} 


export function initializeColumnPickerAction(resource, columns) { 
    return { 
    type: actions.INIT_COLUMNPICKER, 
    columns, 
    meta: { resource }, 
    }; 
} 


export function toggleColumnPickerStatusAction(column) { 
    return { 
    type: actions.TOGGLE_COLUMNPICKER_STATUS, 
    column, 
    }; 
} 

reducers.js:父组件的

import { actions } from './actions'; 

function columnPickerReducer(state = [], action) { 
    switch (action.type) { 
    case actions.INIT_COLUMNPICKER: { 
     console.log('Init columnopicker reducer'); 
     return action.columns; 
    } 
    case actions.TOGGLE_COLUMNPICKER_STATUS: { 
     const columns = state.map((column) => { 
     if (column.source === action.column.source) { 
      return { ...column, checked: !column.checked }; 
     } 
     return column; 
     }); 
     return columns; 
    } 
    default: 
     return state; 
    } 
} 

export default columnPickerReducer; 

例片断:

... 

<ColumnPickableList title="SillyStuff" {...props}> 
    <TextField source="id" /> 
    <TextField source="NAME" /> 
    <TextField source="SILLY_NAME" /> 
    <TextField source="CHANGED_BY" /> 
    <DateField source="CHANGED_TS" showTime /> 
    <EditButton /> 
    <DeleteButton /> 
</ColumnPickableList> 
... 
+0

是对一个错误以上?难道不应该像这样操纵孩子吗? @Gildas – activist

+0

你有没有尝试过这个函数作为子模式?请参阅https://marmelab.com/admin-on-rest/Authorization.html#restricting-access-to-fields-and-inputs。在2.0.0版本中,您无需使用authClient即可运行。同时,如果需要,只需实施一个虚拟的 – Gildas

相关问题