我們將實現一個columnpicker,目前我唯一的想法是實現包裝列表的ColumnPickableList。這也會包含一個複選框列表,使用戶可以隱藏一列。有沒有簡單的方法來實現List列選取器?
但在此之前我繼續做,我只是想知道,如果我reinveting方向盤,如果有解決這個更簡單的方法?
我們將實現一個columnpicker,目前我唯一的想法是實現包裝列表的ColumnPickableList。這也會包含一個複選框列表,使用戶可以隱藏一列。有沒有簡單的方法來實現List列選取器?
但在此之前我繼續做,我只是想知道,如果我reinveting方向盤,如果有解決這個更簡單的方法?
沒有簡單的方法。你必須實現自己的List組件爲
我在這下面了,因爲我努力使這項工作。也許這是因爲我選擇創建一個包裝器來過濾要顯示的孩子。所以在技術上這種方法不會實現自己的列表。
我已經我希望將工作天真的草案,但未能重新渲染孩子,即使他們改變/在父組件過濾。
在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>
...
是對一個錯誤以上?難道不應該像這樣操縱孩子嗎? @Gildas – activist
你有沒有嘗試過這個函數作爲子模式?請參閱https://marmelab.com/admin-on-rest/Authorization.html#restricting-access-to-fields-and-inputs。在2.0.0版本中,您無需使用authClient即可運行。同時,如果需要,只需實施一個虛擬的 – Gildas