2017-10-06 155 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

相關問題