Skip to content

Instantly share code, notes, and snippets.

@radiosterne
Created December 22, 2018 15:44
Show Gist options
  • Save radiosterne/26436a9f7eccfee403856f7bdabd7f12 to your computer and use it in GitHub Desktop.
Save radiosterne/26436a9f7eccfee403856f7bdabd7f12 to your computer and use it in GitHub Desktop.
Antd table with editing example
<meta charset="UTF-8">
<html>
<body>
<div id='root' />
</body>
<script type='text/javascript' src="./dist/index.js"></script>
</html>
import { observer } from 'mobx-react';
import { observable } from 'mobx';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Table, Button } from 'antd';
type ExampleEntity = {
strField: string;
numField: number;
}
// этот тип я уже описывал в ГИС
type PickByType<T, TPropertyType> =
{ [P in keyof T]: T[P] extends TPropertyType ? P : never }[keyof T];
type StringEditorProps<T> = {
item: T,
index: number,
editor: { editingIndex: number },
fieldName: PickByType<T, string>
}
@observer
class StringEditor<T> extends React.Component<StringEditorProps<T>> {
render() {
//вот тут тайпскрипту немного не хватает силы понять, что там всегда стринг, однако там всегда он, и на этапе комплияции это гарантировано
const fieldValue = this.props.item[this.props.fieldName] as unknown as string;
return this.props.index === this.props.editor.editingIndex
? <input type='text' value={fieldValue} onChange={(ev) => this.props.item[this.props.fieldName] = ev.target.value as any} />
: fieldValue;
}
}
@observer
class ExampleComponent extends React.Component<{}> {
constructor(props: {}) {
super(props);
this.data = [
{
strField: '1',
numField: 1
},
{
strField: '2',
numField: 2
},
{
strField: '3',
numField: 3
},
{
strField: '4',
numField: 5
},
]
}
@observable
private data: ExampleEntity[];
@observable
public editingIndex: number | undefined = undefined;
render() {
return <Table
dataSource={this.data}
columns={[
{
title: 'Строка',
key: 'strField',
dataIndex: 'strField',
render: (_, record, index) => <StringEditor
item={record}
index={index}
editor={this}
fieldName='strField' /> //попробуй написать здесь не strField, а numField — не скомпилится
},
{
title: 'Редактировать',
key: 'edit',
render: (_, __, index) => <Button onClick={() => this.editingIndex = index} />
}
]}
/>
}
}
ReactDOM.render(React.createElement(ExampleComponent, {}), document.getElementById('root'));
{
"scripts": {
"build": "./node_modules/.bin/webpack"
},
"dependencies": {
"@types/react": "^16.7.18",
"@types/react-dom": "^16.0.11",
"antd": "^3.11.2",
"mobx": "^5.8.0",
"mobx-react": "^5.4.3",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"ts-loader": "^5.3.2",
"typescript": "^3.2.2",
"webpack": "^4.28.2"
},
"devDependencies": {
"webpack-cli": "^3.1.2"
}
}
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"lib": [ "es6", "dom" ],
"jsx": "react",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"allowJs": true,
"sourceMap": true
},
"compileOnSave": false
}
module.exports = {
entry: './index.tsx',
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ]
},
output: {
filename: 'index.js'
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment