如何基于Material UI选择的表行设置组件状态

时间:2016-10-12 10:02:57

标签: reactjs material-ui

任何帮助学习者表示赞赏的指示。

我正在尝试构建

包含2个输入的表单:

  • 文本字段(患者电子邮件)
  • 一个数组(通过编译选择的表行创建)

我正在尝试设置组件状态以存储文本字段的值和所选表行的数组,以便可以将状态传递给服务器onSubmit。

代码(由占位符数据填充的表行)

import React, { Component } from 'react';
import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton';
import {Table, TableBody, TableFooter, TableHeader, TableHeaderColumn, TableRow, TableRowColumn} from 'material-ui/Table';

const tableData = [{
    feedName: 'Flossing habit',
    messageCount: '12 messages'
}, {
    feedName: 'Post exo instructions',
    messageCount: '5 messages'
}, {
    feedName: 'Appointment feedback',
    messageCount: '1 message'
}];

class NewPatient extends Component {
    constructor (){
        super();
        this.state = ({
            email: "",
            feeds: []
        });
        this.setEmail = this.setEmail.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.onRowSelection = this.onRowSelection.bind(this);
    }
    setEmail(event) {
        console.log(event.target.value);
        this.setState({email: event.target.value})
    }
    handleSubmit(event){
        event.preventDefault();
        console.log(this.state);
        //Meteor.call('console', this.state);
        this.setState({email: ''});
    }
    onRowSelection(rows){
        console.log(rows);
        this.setState({feeds: rows})
    }
    render() {
        let availableFeeds = tableData.map(feed=> {
            return (
                <TableRow key={feed.feedName}>
                    <TableRowColumn>{feed.feedName}</TableRowColumn>
                    <TableRowColumn>{feed.messageCount}</TableRowColumn>
                </TableRow>
            )});
        return (
            <form onSubmit={this.handleSubmit}>
                <TextField
                    name='email'
                    value={this.state.email}
                  onChange={this.setEmail}
                  hintText='Patient email address'
                />
                <Table multiSelectable={true} onRowSelection={this.onRowSelection}>
                    <TableHeader displaySelectAll={false}>
                        <TableRow>
                            <TableHeaderColumn>Feed Name</TableHeaderColumn>
                            <TableHeaderColumn>Number of messages</TableHeaderColumn>
                        </TableRow>
                    </TableHeader>
                    <TableBody>
                        {availableFeeds}
                    </TableBody>
                </Table>
                <RaisedButton type="Submit" label="Send" primary={true} />
            </form>
        )
    }
}
;

export default NewPatient;

我面临的问题

设置所选行数组的组件状态。当我使用时:

onRowSelection(rows){
        console.log(rows);
        this.setState({feeds: rows})
    }
  • 选定的行不会被选中&#39;并且状态也不反映所选行。
  • 如果我从这里删除了setState函数,那么突然可以选择行 - 每当选择改变时,console.log(rows)就显示所选行的更新数组但是如果你把焦点从它上移开,表就会重置(例如,如果您选择一行,然后移至文本字段)。

我怀疑,但我不确定(如果这是问题,也不知道如何使用它,在http://www.material-ui.com/#/components/table的文档中找不到任何内容),我需要在其中添加一个函数&#39; onRowSelection&#39;操纵所选择的&#39;每行内的布尔值..?

有没有人有过这方面的经验,或者看到一些我不知道的东西?

提前感谢任何已经读完这篇文章的人!任何有关链接/文件的建议/指示都非常赞赏。

2 个答案:

答案 0 :(得分:6)

在topteorchef.com的Ryan帮助下找到解决方案后回答:

主要注意事项:

<强> 1。 Material-UI表具有deselectOnClickaway属性 - 确保将其设置为false!

<强> 2。我们需要找到一种方法来为每次选择/取消选择任何其他行时设置每个行的“选定”状态,或者如果表单的另一部分(类似于Shouvik Roy的回答)

import React, { Component } from 'react';
import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton';
// import { _ } from 'meteor/underscore';
import {Table, TableBody, TableFooter, TableHeader, TableHeaderColumn, TableRow, TableRowColumn} from 'material-ui/Table';

const tableData = [{
    feedName: 'Flossing habit',
    messageCount: '12 messages',
    selected: false,
}, {
    feedName: 'Post exo instructions',
    messageCount: '5 messages',
    selected: false,
}, {
    feedName: 'Appointment feedback',
    messageCount: '1 message',
    selected: false,
}];

class NewPatient extends Component {
    constructor (){
        super();
        this.state = ({
            email: "",
            feeds: tableData
        });
        this.setEmail = this.setEmail.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.onRowSelection = this.onRowSelection.bind(this);
    }
    setEmail(event) {
        console.log(event.target.value);
        this.setState({email: event.target.value})
    }
    handleSubmit(event){
        event.preventDefault();
        console.log(this.state);
        Meteor.call('console', this.state.email);
        this.setState({email: ''});
    }
    onRowSelection(rows){
        const selectedFeeds = [];
        this.state.feeds.forEach((feed, i) => {
            feed.selected = rows.indexOf(i) > -1;
            selectedFeeds.push(feed);
        });
    //  console.log(selectedFeeds);
        this.setState({feeds: selectedFeeds}, () => {
            console.log(this.state.feeds);
        });
    }
    render() {
        let availableFeeds = this.state.feeds.map((feed, i)  => {
            return (
                <TableRow key={feed.feedName} selected={feed.selected}>
                    <TableRowColumn>{feed.feedName}</TableRowColumn>
                    <TableRowColumn>{feed.messageCount}</TableRowColumn>
                </TableRow>
            )});
        return (
            <form onSubmit={this.handleSubmit}>
                <TextField
                    name='email'
                    value={this.state.email}
                  onChange={this.setEmail}
                  hintText='Patient email address'
                />
                <Table multiSelectable={true} onRowSelection={this.onRowSelection}>
                    <TableHeader displaySelectAll={false}>
                        <TableRow>
                            <TableHeaderColumn>Feed Name</TableHeaderColumn>
                            <TableHeaderColumn>Number of messages</TableHeaderColumn>
                        </TableRow>
                    </TableHeader>
                    <TableBody deselectOnClickaway={false}>
                        {availableFeeds}
                    </TableBody>
                </Table>
                <RaisedButton type="Submit" label="Send" primary={true} />
            </form>
        )
    }
}
;

export default NewPatient;

答案 1 :(得分:3)

问题似乎是当您在组件上设置状态<p> <span class="Subjekt">Vater</span> <span class="Praedikat">bringt</span> </p>时再次调用并取消选择您的行。解决此问题的最简单方法是从状态读取并在render上设置selected。这是在React中实现受控组件的示例,您可以阅读更多here

这是更新的代码:

TableRow